var pas = {}; var rtl = { quiet: false, debug_load_units: false, debug_rtti: false, debug: function(){ if (rtl.quiet || !console || !console.log) return; console.log(arguments); }, error: function(s){ rtl.debug('Error: ',s); throw s; }, warn: function(s){ rtl.debug('Warn: ',s); }, hasString: function(s){ return rtl.isString(s) && (s.length>0); }, isArray: function(a) { return Array.isArray(a); }, isFunction: function(f){ return typeof(f)==="function"; }, isModule: function(m){ return rtl.isObject(m) && rtl.hasString(m.$name) && (pas[m.$name]===m); }, isImplementation: function(m){ return rtl.isObject(m) && rtl.isModule(m.$module) && (m.$module.$impl===m); }, isNumber: function(n){ return typeof(n)==="number"; }, isObject: function(o){ var s=typeof(o); return (typeof(o)==="object") && (o!=null); }, isString: function(s){ return typeof(s)==="string"; }, getNumber: function(n){ return typeof(n)==="number"?n:NaN; }, getChar: function(c){ return ((typeof(c)==="string") && (c.length===1)) ? c : ""; }, getObject: function(o){ return ((typeof(o)==="object") || (typeof(o)==='function')) ? o : null; }, isPasClass: function(type){ return (rtl.isObject(type) && type.hasOwnProperty('$classname') && rtl.isObject(type.$module)); }, isPasClassInstance: function(type){ return (rtl.isObject(type) && rtl.isPasClass(type.$class)); }, hexStr: function(n,digits){ return ("000000000000000"+n.toString(16).toUpperCase()).slice(-digits); }, m_loading: 0, m_loading_intf: 1, m_intf_loaded: 2, m_loading_impl: 3, // loading all used unit m_initializing: 4, // running initialization m_initialized: 5, module: function(module_name, intfuseslist, intfcode, impluseslist, implcode){ if (rtl.debug_load_units) rtl.debug('rtl.module name="'+module_name+'" intfuses='+intfuseslist+' impluses='+impluseslist+' hasimplcode='+rtl.isFunction(implcode)); if (!rtl.hasString(module_name)) rtl.error('invalid module name "'+module_name+'"'); if (!rtl.isArray(intfuseslist)) rtl.error('invalid interface useslist of "'+module_name+'"'); if (!rtl.isFunction(intfcode)) rtl.error('invalid interface code of "'+module_name+'"'); if (!(impluseslist==undefined) && !rtl.isArray(impluseslist)) rtl.error('invalid implementation useslist of "'+module_name+'"'); if (!(implcode==undefined) && !rtl.isFunction(implcode)) rtl.error('invalid implementation code of "'+module_name+'"'); if (pas[module_name]) rtl.error('module "'+module_name+'" is already registered'); var module = pas[module_name] = { $name: module_name, $intfuseslist: intfuseslist, $impluseslist: impluseslist, $state: rtl.m_loading, $intfcode: intfcode, $implcode: implcode, $impl: null, $rtti: Object.create(rtl.tSectionRTTI) }; module.$rtti.$module = module; if (implcode) module.$impl = { $module: module, $rtti: module.$rtti }; }, exitcode: 0, run: function(module_name){ function doRun(){ if (!rtl.hasString(module_name)) module_name='program'; if (rtl.debug_load_units) rtl.debug('rtl.run module="'+module_name+'"'); rtl.initRTTI(); var module = pas[module_name]; if (!module) rtl.error('rtl.run module "'+module_name+'" missing'); rtl.loadintf(module); rtl.loadimpl(module); if (module_name=='program'){ if (rtl.debug_load_units) rtl.debug('running $main'); var r = pas.program.$main(); if (rtl.isNumber(r)) rtl.exitcode = r; } } if (rtl.showUncaughtExceptions) { try{ doRun(); } catch(re) { var errMsg = re.hasOwnProperty('$class') ? re.$class.$classname : ''; errMsg += ((errMsg) ? ': ' : '') + (re.hasOwnProperty('fMessage') ? re.fMessage : re); alert('Uncaught Exception : '+errMsg); rtl.exitCode = 216; } } else { doRun(); } return rtl.exitcode; }, loadintf: function(module){ if (module.$state>rtl.m_loading_intf) return; // already finished if (rtl.debug_load_units) rtl.debug('loadintf: "'+module.$name+'"'); if (module.$state===rtl.m_loading_intf) rtl.error('unit cycle detected "'+module.$name+'"'); module.$state=rtl.m_loading_intf; // load interfaces of interface useslist rtl.loaduseslist(module,module.$intfuseslist,rtl.loadintf); // run interface if (rtl.debug_load_units) rtl.debug('loadintf: run intf of "'+module.$name+'"'); module.$intfcode(module.$intfuseslist); // success module.$state=rtl.m_intf_loaded; // Note: units only used in implementations are not yet loaded (not even their interfaces) }, loaduseslist: function(module,useslist,f){ if (useslist==undefined) return; for (var i in useslist){ var unitname=useslist[i]; if (rtl.debug_load_units) rtl.debug('loaduseslist of "'+module.$name+'" uses="'+unitname+'"'); if (pas[unitname]==undefined) rtl.error('module "'+module.$name+'" misses "'+unitname+'"'); f(pas[unitname]); } }, loadimpl: function(module){ if (module.$state>=rtl.m_loading_impl) return; // already processing if (module.$state0){ o = this[newinstancefnname](fnname,args); } else { o = Object.create(this); } o.$class = this; // Note: o.$class === Object.getPrototypeOf(o) o.$init(); try{ o[fnname].apply(o,args); if (o.AfterConstruction) o.AfterConstruction(); } catch($e){ o.$destroy; throw $e; } return o; }; c.$destroy = function(fnname){ if (this.BeforeDestruction) this.BeforeDestruction(); this[fnname](); this.$final; }; rtl.initClass(c,parent,name,initfn); }, tObjectDestroy: "Destroy", free: function(obj,name){ if (obj[name]==null) return; obj[name].$destroy(rtl.tObjectDestroy); obj[name]=null; }, freeLoc: function(obj){ if (obj==null) return; obj.$destroy(rtl.tObjectDestroy); return null; }, is: function(instance,type){ return type.isPrototypeOf(instance) || (instance===type); }, isExt: function(instance,type,mode){ // mode===1 means instance must be a Pascal class instance // mode===2 means instance must be a Pascal class // Notes: // isPrototypeOf and instanceof return false on equal // isPrototypeOf does not work for Date.isPrototypeOf(new Date()) // so if isPrototypeOf is false test with instanceof // instanceof needs a function on right side if (instance == null) return false; // Note: ==null checks for undefined too if ((typeof(type) !== 'object') && (typeof(type) !== 'function')) return false; if (instance === type){ if (mode===1) return false; if (mode===2) return rtl.isPasClass(instance); return true; } if (type.isPrototypeOf && type.isPrototypeOf(instance)){ if (mode===1) return rtl.isPasClassInstance(instance); if (mode===2) return rtl.isPasClass(instance); return true; } if ((typeof type == 'function') && (instance instanceof type)) return true; return false; }, Exception: null, EInvalidCast: null, EAbstractError: null, ERangeError: null, raiseE: function(typename){ var t = rtl[typename]; if (t==null){ var mod = pas.SysUtils; if (!mod) mod = pas.sysutils; if (mod){ t = mod[typename]; if (!t) t = mod[typename.toLowerCase()]; if (!t) t = mod['Exception']; if (!t) t = mod['exception']; } } if (t){ if (t.Create){ throw t.$create("Create"); } else if (t.create){ throw t.$create("create"); } } if (typename === "EInvalidCast") throw "invalid type cast"; if (typename === "EAbstractError") throw "Abstract method called"; if (typename === "ERangeError") throw "range error"; throw typename; }, as: function(instance,type){ if((instance === null) || rtl.is(instance,type)) return instance; rtl.raiseE("EInvalidCast"); }, asExt: function(instance,type,mode){ if((instance === null) || rtl.isExt(instance,type,mode)) return instance; rtl.raiseE("EInvalidCast"); }, createInterface: function(module, name, guid, fnnames, ancestor, initfn){ //console.log('createInterface name="'+name+'" guid="'+guid+'" names='+fnnames); var i = ancestor?Object.create(ancestor):{}; module[name] = i; i.$module = module; i.$name = name; i.$fullname = module.$name+'.'+name; i.$guid = guid; i.$guidr = null; i.$names = fnnames?fnnames:[]; if (rtl.isFunction(initfn)){ // rtti if (rtl.debug_rtti) rtl.debug('createInterface '+i.$fullname); var t = i.$module.$rtti.$Interface(name,{ "interface": i, module: module }); i.$rtti = t; if (ancestor) t.ancestor = ancestor.$rtti; if (!t.ancestor) t.ancestor = null; initfn.call(i); } return i; }, strToGUIDR: function(s,g){ var p = 0; function n(l){ var h = s.substr(p,l); p+=l; return parseInt(h,16); } p+=1; // skip { g.D1 = n(8); p+=1; // skip - g.D2 = n(4); p+=1; // skip - g.D3 = n(4); p+=1; // skip - if (!g.D4) g.D4=[]; g.D4[0] = n(2); g.D4[1] = n(2); p+=1; // skip - for(var i=2; i<8; i++) g.D4[i] = n(2); return g; }, guidrToStr: function(g){ if (g.$intf) return g.$intf.$guid; var h = rtl.hexStr; var s='{'+h(g.D1,8)+'-'+h(g.D2,4)+'-'+h(g.D3,4)+'-'+h(g.D4[0],2)+h(g.D4[1],2)+'-'; for (var i=2; i<8; i++) s+=h(g.D4[i],2); s+='}'; return s; }, createTGUID: function(guid){ var TGuid = (pas.System)?pas.System.TGuid:pas.system.tguid; var g = rtl.strToGUIDR(guid,new TGuid()); return g; }, getIntfGUIDR: function(intfTypeOrVar){ if (!intfTypeOrVar) return null; if (!intfTypeOrVar.$guidr){ var g = rtl.createTGUID(intfTypeOrVar.$guid); if (!intfTypeOrVar.hasOwnProperty('$guid')) intfTypeOrVar = Object.getPrototypeOf(intfTypeOrVar); g.$intf = intfTypeOrVar; intfTypeOrVar.$guidr = g; } return intfTypeOrVar.$guidr; }, addIntf: function (aclass, intf, map){ function jmp(fn){ if (typeof(fn)==="function"){ return function(){ return fn.apply(this.$o,arguments); }; } else { return function(){ rtl.raiseE('EAbstractError'); }; } } if(!map) map = {}; var t = intf; var item = Object.create(t); aclass.$intfmaps[intf.$guid] = item; do{ var names = t.$names; if (!names) break; for (var i=0; i=minval) && (i<=maxval)) return i; rtl.raiseE('ERangeError'); }, rcc: function(c,minval,maxval){ // range check char if ((typeof(c)==='string') && (c.length===1)){ var i = c.charCodeAt(0); if ((i>=minval) && (i<=maxval)) return c; } rtl.raiseE('ERangeError'); }, rcSetCharAt: function(s,index,c){ // range check setCharAt if ((typeof(s)!=='string') || (index<0) || (index>=s.length)) rtl.raiseE('ERangeError'); return rtl.setCharAt(s,index,c); }, rcCharAt: function(s,index){ // range check charAt if ((typeof(s)!=='string') || (index<0) || (index>=s.length)) rtl.raiseE('ERangeError'); return s.charAt(index); }, rcArrR: function(arr,index){ // range check read array if (Array.isArray(arr) && (typeof(index)==='number') && (index>=0) && (index2){ // arr,index1,index2,... arr=arr[index]; for (var i=2; i=0) && (indexsrcarray.length) end = srcarray.length; if (index>=end) return []; if (type===0){ return srcarray.slice(index,end); } else { var a = []; a.length = end-index; rtl.arrayClone(type,srcarray,index,end,a,0); return a; } }, setCharAt: function(s,index,c){ return s.substr(0,index)+c+s.substr(index+1); }, getResStr: function(mod,name){ var rs = mod.$resourcestrings[name]; return rs.current?rs.current:rs.org; }, createSet: function(){ var s = {}; for (var i=0; i newlen){ return s.substring(0,newlen); } else if (s.repeat){ // Note: repeat needs ECMAScript6! return s+' '.repeat(newlen-oldlen); } else { while (oldlen=width) return s; if (s.repeat){ // Note: repeat needs ECMAScript6! return ' '.repeat(width-l) + s; } else { while (l2){ return rtl.spaceLeft(d.toFixed(p),w); } else { // exponent width var pad = ""; var ad = Math.abs(d); if (ad<1.0e+10) { pad='00'; } else if (ad<1.0e+100) { pad='0'; } if (arguments.length<2) { w=9; } else if (w<9) { w=9; } var p = w-8; var s=(d>0 ? " " : "" ) + d.toExponential(p); s=s.replace(/e(.)/,'E$1'+pad); return rtl.spaceLeft(s,w); } }, initRTTI: function(){ if (rtl.debug_rtti) rtl.debug('initRTTI'); // base types rtl.tTypeInfo = { name: "tTypeInfo" }; function newBaseTI(name,kind,ancestor){ if (!ancestor) ancestor = rtl.tTypeInfo; if (rtl.debug_rtti) rtl.debug('initRTTI.newBaseTI "'+name+'" '+kind+' ("'+ancestor.name+'")'); var t = Object.create(ancestor); t.name = name; t.kind = kind; rtl[name] = t; return t; }; function newBaseInt(name,minvalue,maxvalue,ordtype){ var t = newBaseTI(name,1 /* tkInteger */,rtl.tTypeInfoInteger); t.minvalue = minvalue; t.maxvalue = maxvalue; t.ordtype = ordtype; return t; }; newBaseTI("tTypeInfoInteger",1 /* tkInteger */); newBaseInt("shortint",-0x80,0x7f,0); newBaseInt("byte",0,0xff,1); newBaseInt("smallint",-0x8000,0x7fff,2); newBaseInt("word",0,0xffff,3); newBaseInt("longint",-0x80000000,0x7fffffff,4); newBaseInt("longword",0,0xffffffff,5); newBaseInt("nativeint",-0x10000000000000,0xfffffffffffff,6); newBaseInt("nativeuint",0,0xfffffffffffff,7); newBaseTI("char",2 /* tkChar */); newBaseTI("string",3 /* tkString */); newBaseTI("tTypeInfoEnum",4 /* tkEnumeration */,rtl.tTypeInfoInteger); newBaseTI("tTypeInfoSet",5 /* tkSet */); newBaseTI("double",6 /* tkDouble */); newBaseTI("boolean",7 /* tkBool */); newBaseTI("tTypeInfoProcVar",8 /* tkProcVar */); newBaseTI("tTypeInfoMethodVar",9 /* tkMethod */,rtl.tTypeInfoProcVar); newBaseTI("tTypeInfoArray",10 /* tkArray */); newBaseTI("tTypeInfoDynArray",11 /* tkDynArray */); newBaseTI("tTypeInfoPointer",15 /* tkPointer */); var t = newBaseTI("pointer",15 /* tkPointer */,rtl.tTypeInfoPointer); t.reftype = null; newBaseTI("jsvalue",16 /* tkJSValue */); newBaseTI("tTypeInfoRefToProcVar",17 /* tkRefToProcVar */,rtl.tTypeInfoProcVar); // member kinds rtl.tTypeMember = {}; function newMember(name,kind){ var m = Object.create(rtl.tTypeMember); m.name = name; m.kind = kind; rtl[name] = m; }; newMember("tTypeMemberField",1); // tmkField newMember("tTypeMemberMethod",2); // tmkMethod newMember("tTypeMemberProperty",3); // tmkProperty // base object for storing members: a simple object rtl.tTypeMembers = {}; // tTypeInfoStruct - base object for tTypeInfoClass, tTypeInfoRecord, tTypeInfoInterface var tis = newBaseTI("tTypeInfoStruct",0); tis.$addMember = function(name,ancestor,options){ if (rtl.debug_rtti){ if (!rtl.hasString(name) || (name.charAt()==='$')) throw 'invalid member "'+name+'", this="'+this.name+'"'; if (!rtl.is(ancestor,rtl.tTypeMember)) throw 'invalid ancestor "'+ancestor+':'+ancestor.name+'", "'+this.name+'.'+name+'"'; if ((options!=undefined) && (typeof(options)!='object')) throw 'invalid options "'+options+'", "'+this.name+'.'+name+'"'; }; var t = Object.create(ancestor); t.name = name; this.members[name] = t; this.names.push(name); if (rtl.isObject(options)){ for (var key in options) if (options.hasOwnProperty(key)) t[key] = options[key]; }; return t; }; tis.addField = function(name,type,options){ var t = this.$addMember(name,rtl.tTypeMemberField,options); if (rtl.debug_rtti){ if (!rtl.is(type,rtl.tTypeInfo)) throw 'invalid type "'+type+'", "'+this.name+'.'+name+'"'; }; t.typeinfo = type; this.fields.push(name); return t; }; tis.addFields = function(){ var i=0; while(i 0) { x = FMod(x,Self.repeatValue); y = FMod(y,Self.repeatValue); z = FMod(z,Self.repeatValue); }; xi = pas.math.Floor(x) & 255; yi = pas.math.Floor(y) & 255; zi = pas.math.Floor(z) & 255; xf = x - pas.math.Floor(x); yf = y - pas.math.Floor(y); zf = z - pas.math.Floor(z); u = Self.Fade(xf); v = Self.Fade(yf); w = Self.Fade(zf); aaa = Self.p[Self.p[Self.p[xi] + yi] + zi]; aba = Self.p[Self.p[Self.p[xi] + Self.Inc(yi)] + zi]; aab = Self.p[Self.p[Self.p[xi] + yi] + Self.Inc(zi)]; abb = Self.p[Self.p[Self.p[xi] + Self.Inc(yi)] + Self.Inc(zi)]; baa = Self.p[Self.p[Self.p[Self.Inc(xi)] + yi] + zi]; bba = Self.p[Self.p[Self.p[Self.Inc(xi)] + Self.Inc(yi)] + zi]; bab = Self.p[Self.p[Self.p[Self.Inc(xi)] + yi] + Self.Inc(zi)]; bbb = Self.p[Self.p[Self.p[Self.Inc(xi)] + Self.Inc(yi)] + Self.Inc(zi)]; x1 = Self.Lerp(Self.Grad(aaa,xf,yf,zf),Self.Grad(baa,xf - 1,yf,zf),u); x2 = Self.Lerp(Self.Grad(aba,xf,yf - 1,zf),Self.Grad(bba,xf - 1,yf - 1,zf),u); y1 = Self.Lerp(x1,x2,v); x1 = Self.Lerp(Self.Grad(aab,xf,yf,zf - 1),Self.Grad(bab,xf - 1,yf,zf - 1),u); x2 = Self.Lerp(Self.Grad(abb,xf,yf - 1,zf - 1),Self.Grad(bbb,xf - 1,yf - 1,zf - 1),u); y2 = Self.Lerp(x1,x2,v); Result = (Self.Lerp(y1,y2,w) + 1) / 2; return Result; }; this.GetValue$1 = function (x, y, z, octaves, persistence) { var Result = 0.0; var total = 0; var frequency = 1; var amplitude = 1; var maxValue = 0; var i = 0; for (var $l1 = 0, $end2 = octaves - 1; $l1 <= $end2; $l1++) { i = $l1; total += this.GetValue(x * frequency,y * frequency,z * frequency) * amplitude; maxValue += amplitude; amplitude *= persistence; frequency *= 2; }; Result = total / maxValue; return Result; }; this.GetNoise = function (x, y, width, height, scale, frequency) { var Result = 0.0; var nx = 0.0; var ny = 0.0; nx = (x / width) - 0.5; ny = (y / height) - 0.5; Result = (this.GetValue$1(nx * scale,ny * scale,0,frequency,0.5) / 2) + 0.5; return Result; }; this.Inc = function (num) { var Result = 0; num += 1; if (this.repeatValue > 0) num = num % this.repeatValue; Result = num; return Result; }; this.Grad = function (hash, x, y, z) { var Result = 0.0; var $tmp1 = hash & 0xF; if ($tmp1 === 0x0) { Result = x + y} else if ($tmp1 === 0x1) { Result = -x + y} else if ($tmp1 === 0x2) { Result = x - y} else if ($tmp1 === 0x3) { Result = -x - y} else if ($tmp1 === 0x4) { Result = x + z} else if ($tmp1 === 0x5) { Result = -x + z} else if ($tmp1 === 0x6) { Result = x - z} else if ($tmp1 === 0x7) { Result = -x - z} else if ($tmp1 === 0x8) { Result = y + z} else if ($tmp1 === 0x9) { Result = -y + z} else if ($tmp1 === 0xA) { Result = y - z} else if ($tmp1 === 0xB) { Result = -y - z} else if ($tmp1 === 0xC) { Result = y + x} else if ($tmp1 === 0xD) { Result = -y + z} else if ($tmp1 === 0xE) { Result = y - x} else if ($tmp1 === 0xF) { Result = -y - z} else { Result = 0; }; return Result; }; this.Fade = function (t) { var Result = 0.0; Result = ((t * t) * t) * ((t * ((t * 6) - 15)) + 10); return Result; }; this.Lerp = function (a, b, x) { var Result = 0.0; Result = a + (x * (b - a)); return Result; }; }); this.RandomNoiseSeed = function (seed) { var Result = rtl.arraySetLength(null,0,256); var i = 0; for (i = 0; i <= 255; i++) Result[i] = pas.System.Random(256); return Result; }; }); rtl.module("Matrix",["System","JS"],function () { "use strict"; var $mod = this; rtl.createClass($mod,"TMatrix",pas.System.TObject,function () { this.$init = function () { pas.System.TObject.$init.call(this); this.table = null; this.width = 0; this.height = 0; }; this.$final = function () { this.table = undefined; pas.System.TObject.$final.call(this); }; this.Create$1 = function (w, h) { this.width = w; this.height = h; this.table = new Array(this.width * this.height); }; this.SetValue = function (x, y, value) { this.table[this.IndexFor(x,y)] = value; }; this.GetValue = function (x, y) { var Result = undefined; Result = this.table[this.IndexFor(x,y)]; return Result; }; this.GetWidth = function () { var Result = 0; Result = this.width; return Result; }; this.GetHeight = function () { var Result = 0; Result = this.height; return Result; }; this.IndexFor = function (x, y) { var Result = 0; Result = x + (y * this.height); return Result; }; }); }); rtl.module("Web",["System","JS"],function () { "use strict"; var $mod = this; }); rtl.module("webgl",["System","JS","Web"],function () { "use strict"; var $mod = this; }); rtl.module("GLTypes",["System","webgl","JS","math","SysUtils"],function () { "use strict"; var $mod = this; this.TVec2 = function (s) { if (s) { this.x = s.x; this.y = s.y; } else { this.x = 0.0; this.y = 0.0; }; this.$equal = function (b) { return (this.x === b.x) && (this.y === b.y); }; }; this.TVec3 = function (s) { if (s) { this.x = s.x; this.y = s.y; this.z = s.z; } else { this.x = 0.0; this.y = 0.0; this.z = 0.0; }; this.$equal = function (b) { return (this.x === b.x) && ((this.y === b.y) && (this.z === b.z)); }; }; this.V3 = function (x, y, z) { var Result = new $mod.TVec3(); Result.x = x; Result.y = y; Result.z = z; return Result; }; this.Divide = function (v, amount) { var Result = new $mod.TVec3(); Result = new $mod.TVec3($mod.V3(v.x / amount,v.y / amount,v.z / amount)); return Result; }; this.Magnitude = function (v) { var Result = 0.0; Result = Math.sqrt((Math.pow(v.x,2) + Math.pow(v.y,2)) + Math.pow(v.z,2)); return Result; }; this.Normalize = function (v) { var Result = new $mod.TVec3(); Result = new $mod.TVec3($mod.Divide(new $mod.TVec3(v),$mod.Magnitude(new $mod.TVec3(v)))); return Result; }; this.V2 = function (x, y) { var Result = new $mod.TVec2(); Result.x = x; Result.y = y; return Result; }; }); rtl.module("browserconsole",["System","JS","Web"],function () { "use strict"; var $mod = this; var $impl = $mod.$impl; this.DefaultMaxConsoleLines = 25; this.DefaultConsoleStyle = (((((((((((".pasconsole { " + pas.System.sLineBreak) + "font-family: courier;") + pas.System.sLineBreak) + "font-size: 14px;") + pas.System.sLineBreak) + "background: #FFFFFF;") + pas.System.sLineBreak) + "color: #000000;") + pas.System.sLineBreak) + "display: block;") + pas.System.sLineBreak) + "}"; this.ConsoleElementID = ""; this.ConsoleStyle = ""; this.MaxConsoleLines = 0; this.ConsoleLinesToBrowserLog = false; this.ResetConsole = function () { if ($impl.LinesParent === null) return; while ($impl.LinesParent.firstElementChild !== null) $impl.LinesParent.removeChild($impl.LinesParent.firstElementChild); $impl.AppendLine(); }; this.InitConsole = function () { if ($impl.ConsoleElement === null) return; if ($impl.ConsoleElement.nodeName.toLowerCase() !== "body") { while ($impl.ConsoleElement.firstElementChild !== null) $impl.ConsoleElement.removeChild($impl.ConsoleElement.firstElementChild); }; $impl.StyleElement = document.createElement("style"); $impl.StyleElement.innerText = $mod.ConsoleStyle; $impl.ConsoleElement.appendChild($impl.StyleElement); $impl.LinesParent = document.createElement("div"); $impl.ConsoleElement.appendChild($impl.LinesParent); }; this.HookConsole = function () { $impl.ConsoleElement = null; if ($mod.ConsoleElementID !== "") $impl.ConsoleElement = document.getElementById($mod.ConsoleElementID); if ($impl.ConsoleElement === null) $impl.ConsoleElement = document.body; if ($impl.ConsoleElement === null) return; $mod.InitConsole(); $mod.ResetConsole(); pas.System.SetWriteCallBack($impl.WriteConsole); }; $mod.$init = function () { $mod.ConsoleLinesToBrowserLog = true; $mod.ConsoleElementID = "pasjsconsole"; $mod.ConsoleStyle = $mod.DefaultConsoleStyle; $mod.MaxConsoleLines = 25; $mod.HookConsole(); }; },null,function () { "use strict"; var $mod = this; var $impl = $mod.$impl; $impl.LastLine = null; $impl.StyleElement = null; $impl.LinesParent = null; $impl.ConsoleElement = null; $impl.AppendLine = function () { var CurrentCount = 0; var S = null; CurrentCount = 0; S = $impl.LinesParent.firstChild; while (S != null) { CurrentCount += 1; S = S.nextSibling; }; while (CurrentCount > $mod.MaxConsoleLines) { CurrentCount -= 1; $impl.LinesParent.removeChild($impl.LinesParent.firstChild); }; $impl.LastLine = document.createElement("div"); $impl.LastLine.className = "pasconsole"; $impl.LinesParent.appendChild($impl.LastLine); }; $impl.WriteConsole = function (S, NewLine) { var CL = ""; CL = $impl.LastLine.innerText; CL = CL + ("" + S); $impl.LastLine.innerText = CL; if (NewLine) { if ($mod.ConsoleLinesToBrowserLog) window.console.log(CL); $impl.AppendLine(); }; }; }); rtl.module("Mat4",["System","browserconsole","JS","math"],function () { "use strict"; var $mod = this; var $impl = $mod.$impl; rtl.createClass($mod,"TMat4",pas.System.TObject,function () { this.$init = function () { pas.System.TObject.$init.call(this); this.RawComponents = rtl.arraySetLength(null,0.0,4,4); }; this.$final = function () { this.RawComponents = undefined; pas.System.TObject.$final.call(this); }; this.Identity = function () { this.RawComponents[0][0] = 1.0; this.RawComponents[0][1] = 0.0; this.RawComponents[0][2] = 0.0; this.RawComponents[0][3] = 0.0; this.RawComponents[1][0] = 0.0; this.RawComponents[1][1] = 1.0; this.RawComponents[1][2] = 0.0; this.RawComponents[1][3] = 0.0; this.RawComponents[2][0] = 0.0; this.RawComponents[2][1] = 0.0; this.RawComponents[2][2] = 1.0; this.RawComponents[2][3] = 0.0; this.RawComponents[3][0] = 0.0; this.RawComponents[3][1] = 0.0; this.RawComponents[3][2] = 0.0; this.RawComponents[3][3] = 1.0; }; this.Translate = function (tx, ty, tz) { this.RawComponents[0][0] = 1.0; this.RawComponents[0][1] = 0.0; this.RawComponents[0][2] = 0.0; this.RawComponents[0][3] = 0.0; this.RawComponents[1][0] = 0.0; this.RawComponents[1][1] = 1.0; this.RawComponents[1][2] = 0.0; this.RawComponents[1][3] = 0.0; this.RawComponents[2][0] = 0.0; this.RawComponents[2][1] = 0.0; this.RawComponents[2][2] = 1.0; this.RawComponents[2][3] = 0.0; this.RawComponents[3][0] = tx; this.RawComponents[3][1] = ty; this.RawComponents[3][2] = tz; this.RawComponents[3][3] = 1.0; }; this.Perspective = function (fovy, Aspect, zNear, zFar) { var Sine = 0.0; var Cotangent = 0.0; var ZDelta = 0.0; var Radians = 0.0; Radians = (fovy * 0.5) * 0.017453292519944444; ZDelta = zFar - zNear; Sine = Math.sin(Radians); if (!(((ZDelta === 0) || (Sine === 0)) || (Aspect === 0))) { Cotangent = Math.cos(Radians) / Sine; this.RawComponents = $impl.Matrix4x4Identity.RawComponents.slice(0); this.RawComponents[0][0] = Cotangent / Aspect; this.RawComponents[1][1] = Cotangent; this.RawComponents[2][2] = -(zFar + zNear) / ZDelta; this.RawComponents[2][3] = -1 - 0; this.RawComponents[3][2] = -((2.0 * zNear) * zFar) / ZDelta; this.RawComponents[3][3] = 0.0; }; }; this.Multiply = function (m) { var Result = null; Result = $mod.TMat4.$create("Identity"); Result.RawComponents[0][0] = (((m.RawComponents[0][0] * this.RawComponents[0][0]) + (m.RawComponents[0][1] * this.RawComponents[1][0])) + (m.RawComponents[0][2] * this.RawComponents[2][0])) + (m.RawComponents[0][3] * this.RawComponents[3][0]); Result.RawComponents[0][1] = (((m.RawComponents[0][0] * this.RawComponents[0][1]) + (m.RawComponents[0][1] * this.RawComponents[1][1])) + (m.RawComponents[0][2] * this.RawComponents[2][1])) + (m.RawComponents[0][3] * this.RawComponents[3][1]); Result.RawComponents[0][2] = (((m.RawComponents[0][0] * this.RawComponents[0][2]) + (m.RawComponents[0][1] * this.RawComponents[1][2])) + (m.RawComponents[0][2] * this.RawComponents[2][2])) + (m.RawComponents[0][3] * this.RawComponents[3][2]); Result.RawComponents[0][3] = (((m.RawComponents[0][0] * this.RawComponents[0][3]) + (m.RawComponents[0][1] * this.RawComponents[1][3])) + (m.RawComponents[0][2] * this.RawComponents[2][3])) + (m.RawComponents[0][3] * this.RawComponents[3][3]); Result.RawComponents[1][0] = (((m.RawComponents[1][0] * this.RawComponents[0][0]) + (m.RawComponents[1][1] * this.RawComponents[1][0])) + (m.RawComponents[1][2] * this.RawComponents[2][0])) + (m.RawComponents[1][3] * this.RawComponents[3][0]); Result.RawComponents[1][1] = (((m.RawComponents[1][0] * this.RawComponents[0][1]) + (m.RawComponents[1][1] * this.RawComponents[1][1])) + (m.RawComponents[1][2] * this.RawComponents[2][1])) + (m.RawComponents[1][3] * this.RawComponents[3][1]); Result.RawComponents[1][2] = (((m.RawComponents[1][0] * this.RawComponents[0][2]) + (m.RawComponents[1][1] * this.RawComponents[1][2])) + (m.RawComponents[1][2] * this.RawComponents[2][2])) + (m.RawComponents[1][3] * this.RawComponents[3][2]); Result.RawComponents[1][3] = (((m.RawComponents[1][0] * this.RawComponents[0][3]) + (m.RawComponents[1][1] * this.RawComponents[1][3])) + (m.RawComponents[1][2] * this.RawComponents[2][3])) + (m.RawComponents[1][3] * this.RawComponents[3][3]); Result.RawComponents[2][0] = (((m.RawComponents[2][0] * this.RawComponents[0][0]) + (m.RawComponents[2][1] * this.RawComponents[1][0])) + (m.RawComponents[2][2] * this.RawComponents[2][0])) + (m.RawComponents[2][3] * this.RawComponents[3][0]); Result.RawComponents[2][1] = (((m.RawComponents[2][0] * this.RawComponents[0][1]) + (m.RawComponents[2][1] * this.RawComponents[1][1])) + (m.RawComponents[2][2] * this.RawComponents[2][1])) + (m.RawComponents[2][3] * this.RawComponents[3][1]); Result.RawComponents[2][2] = (((m.RawComponents[2][0] * this.RawComponents[0][2]) + (m.RawComponents[2][1] * this.RawComponents[1][2])) + (m.RawComponents[2][2] * this.RawComponents[2][2])) + (m.RawComponents[2][3] * this.RawComponents[3][2]); Result.RawComponents[2][3] = (((m.RawComponents[2][0] * this.RawComponents[0][3]) + (m.RawComponents[2][1] * this.RawComponents[1][3])) + (m.RawComponents[2][2] * this.RawComponents[2][3])) + (m.RawComponents[2][3] * this.RawComponents[3][3]); Result.RawComponents[3][0] = (((m.RawComponents[3][0] * this.RawComponents[0][0]) + (m.RawComponents[3][1] * this.RawComponents[1][0])) + (m.RawComponents[3][2] * this.RawComponents[2][0])) + (m.RawComponents[3][3] * this.RawComponents[3][0]); Result.RawComponents[3][1] = (((m.RawComponents[3][0] * this.RawComponents[0][1]) + (m.RawComponents[3][1] * this.RawComponents[1][1])) + (m.RawComponents[3][2] * this.RawComponents[2][1])) + (m.RawComponents[3][3] * this.RawComponents[3][1]); Result.RawComponents[3][2] = (((m.RawComponents[3][0] * this.RawComponents[0][2]) + (m.RawComponents[3][1] * this.RawComponents[1][2])) + (m.RawComponents[3][2] * this.RawComponents[2][2])) + (m.RawComponents[3][3] * this.RawComponents[3][2]); Result.RawComponents[3][3] = (((m.RawComponents[3][0] * this.RawComponents[0][3]) + (m.RawComponents[3][1] * this.RawComponents[1][3])) + (m.RawComponents[3][2] * this.RawComponents[2][3])) + (m.RawComponents[3][3] * this.RawComponents[3][3]); return Result; }; this.Inverse = function () { var Result = null; var t0 = 0.0; var t4 = 0.0; var t8 = 0.0; var t12 = 0.0; var d = 0.0; t0 = ((((((this.RawComponents[1][1] * this.RawComponents[2][2]) * this.RawComponents[3][3]) - ((this.RawComponents[1][1] * this.RawComponents[2][3]) * this.RawComponents[3][2])) - ((this.RawComponents[2][1] * this.RawComponents[1][2]) * this.RawComponents[3][3])) + ((this.RawComponents[2][1] * this.RawComponents[1][3]) * this.RawComponents[3][2])) + ((this.RawComponents[3][1] * this.RawComponents[1][2]) * this.RawComponents[2][3])) - ((this.RawComponents[3][1] * this.RawComponents[1][3]) * this.RawComponents[2][2]); t4 = ((((-((this.RawComponents[1][0] * this.RawComponents[2][2]) * this.RawComponents[3][3]) + ((this.RawComponents[1][0] * this.RawComponents[2][3]) * this.RawComponents[3][2])) + ((this.RawComponents[2][0] * this.RawComponents[1][2]) * this.RawComponents[3][3])) - ((this.RawComponents[2][0] * this.RawComponents[1][3]) * this.RawComponents[3][2])) - ((this.RawComponents[3][0] * this.RawComponents[1][2]) * this.RawComponents[2][3])) + ((this.RawComponents[3][0] * this.RawComponents[1][3]) * this.RawComponents[2][2]); t8 = ((((((this.RawComponents[1][0] * this.RawComponents[2][1]) * this.RawComponents[3][3]) - ((this.RawComponents[1][0] * this.RawComponents[2][3]) * this.RawComponents[3][1])) - ((this.RawComponents[2][0] * this.RawComponents[1][1]) * this.RawComponents[3][3])) + ((this.RawComponents[2][0] * this.RawComponents[1][3]) * this.RawComponents[3][1])) + ((this.RawComponents[3][0] * this.RawComponents[1][1]) * this.RawComponents[2][3])) - ((this.RawComponents[3][0] * this.RawComponents[1][3]) * this.RawComponents[2][1]); t12 = ((((-((this.RawComponents[1][0] * this.RawComponents[2][1]) * this.RawComponents[3][2]) + ((this.RawComponents[1][0] * this.RawComponents[2][2]) * this.RawComponents[3][1])) + ((this.RawComponents[2][0] * this.RawComponents[1][1]) * this.RawComponents[3][2])) - ((this.RawComponents[2][0] * this.RawComponents[1][2]) * this.RawComponents[3][1])) - ((this.RawComponents[3][0] * this.RawComponents[1][1]) * this.RawComponents[2][2])) + ((this.RawComponents[3][0] * this.RawComponents[1][2]) * this.RawComponents[2][1]); d = (((this.RawComponents[0][0] * t0) + (this.RawComponents[0][1] * t4)) + (this.RawComponents[0][2] * t8)) + (this.RawComponents[0][3] * t12); Result = $mod.TMat4.$create("Identity"); if (d !== 0.0) { d = 1.0 / d; Result.RawComponents[0][0] = t0 * d; Result.RawComponents[0][1] = (((((-((this.RawComponents[0][1] * this.RawComponents[2][2]) * this.RawComponents[3][3]) + ((this.RawComponents[0][1] * this.RawComponents[2][3]) * this.RawComponents[3][2])) + ((this.RawComponents[2][1] * this.RawComponents[0][2]) * this.RawComponents[3][3])) - ((this.RawComponents[2][1] * this.RawComponents[0][3]) * this.RawComponents[3][2])) - ((this.RawComponents[3][1] * this.RawComponents[0][2]) * this.RawComponents[2][3])) + ((this.RawComponents[3][1] * this.RawComponents[0][3]) * this.RawComponents[2][2])) * d; Result.RawComponents[0][2] = (((((((this.RawComponents[0][1] * this.RawComponents[1][2]) * this.RawComponents[3][3]) - ((this.RawComponents[0][1] * this.RawComponents[1][3]) * this.RawComponents[3][2])) - ((this.RawComponents[1][1] * this.RawComponents[0][2]) * this.RawComponents[3][3])) + ((this.RawComponents[1][1] * this.RawComponents[0][3]) * this.RawComponents[3][2])) + ((this.RawComponents[3][1] * this.RawComponents[0][2]) * this.RawComponents[1][3])) - ((this.RawComponents[3][1] * this.RawComponents[0][3]) * this.RawComponents[1][2])) * d; Result.RawComponents[0][3] = (((((-((this.RawComponents[0][1] * this.RawComponents[1][2]) * this.RawComponents[2][3]) + ((this.RawComponents[0][1] * this.RawComponents[1][3]) * this.RawComponents[2][2])) + ((this.RawComponents[1][1] * this.RawComponents[0][2]) * this.RawComponents[2][3])) - ((this.RawComponents[1][1] * this.RawComponents[0][3]) * this.RawComponents[2][2])) - ((this.RawComponents[2][1] * this.RawComponents[0][2]) * this.RawComponents[1][3])) + ((this.RawComponents[2][1] * this.RawComponents[0][3]) * this.RawComponents[1][2])) * d; Result.RawComponents[1][0] = t4 * d; Result.RawComponents[1][1] = (((((((this.RawComponents[0][0] * this.RawComponents[2][2]) * this.RawComponents[3][3]) - ((this.RawComponents[0][0] * this.RawComponents[2][3]) * this.RawComponents[3][2])) - ((this.RawComponents[2][0] * this.RawComponents[0][2]) * this.RawComponents[3][3])) + ((this.RawComponents[2][0] * this.RawComponents[0][3]) * this.RawComponents[3][2])) + ((this.RawComponents[3][0] * this.RawComponents[0][2]) * this.RawComponents[2][3])) - ((this.RawComponents[3][0] * this.RawComponents[0][3]) * this.RawComponents[2][2])) * d; Result.RawComponents[1][2] = (((((-((this.RawComponents[0][0] * this.RawComponents[1][2]) * this.RawComponents[3][3]) + ((this.RawComponents[0][0] * this.RawComponents[1][3]) * this.RawComponents[3][2])) + ((this.RawComponents[1][0] * this.RawComponents[0][2]) * this.RawComponents[3][3])) - ((this.RawComponents[1][0] * this.RawComponents[0][3]) * this.RawComponents[3][2])) - ((this.RawComponents[3][0] * this.RawComponents[0][2]) * this.RawComponents[1][3])) + ((this.RawComponents[3][0] * this.RawComponents[0][3]) * this.RawComponents[1][2])) * d; Result.RawComponents[1][3] = (((((((this.RawComponents[0][0] * this.RawComponents[1][2]) * this.RawComponents[2][3]) - ((this.RawComponents[0][0] * this.RawComponents[1][3]) * this.RawComponents[2][2])) - ((this.RawComponents[1][0] * this.RawComponents[0][2]) * this.RawComponents[2][3])) + ((this.RawComponents[1][0] * this.RawComponents[0][3]) * this.RawComponents[2][2])) + ((this.RawComponents[2][0] * this.RawComponents[0][2]) * this.RawComponents[1][3])) - ((this.RawComponents[2][0] * this.RawComponents[0][3]) * this.RawComponents[1][2])) * d; Result.RawComponents[2][0] = t8 * d; Result.RawComponents[2][1] = (((((-((this.RawComponents[0][0] * this.RawComponents[2][1]) * this.RawComponents[3][3]) + ((this.RawComponents[0][0] * this.RawComponents[2][3]) * this.RawComponents[3][1])) + ((this.RawComponents[2][0] * this.RawComponents[0][1]) * this.RawComponents[3][3])) - ((this.RawComponents[2][0] * this.RawComponents[0][3]) * this.RawComponents[3][1])) - ((this.RawComponents[3][0] * this.RawComponents[0][1]) * this.RawComponents[2][3])) + ((this.RawComponents[3][0] * this.RawComponents[0][3]) * this.RawComponents[2][1])) * d; Result.RawComponents[2][2] = (((((((this.RawComponents[0][0] * this.RawComponents[1][1]) * this.RawComponents[3][3]) - ((this.RawComponents[0][0] * this.RawComponents[1][3]) * this.RawComponents[3][1])) - ((this.RawComponents[1][0] * this.RawComponents[0][1]) * this.RawComponents[3][3])) + ((this.RawComponents[1][0] * this.RawComponents[0][3]) * this.RawComponents[3][1])) + ((this.RawComponents[3][0] * this.RawComponents[0][1]) * this.RawComponents[1][3])) - ((this.RawComponents[3][0] * this.RawComponents[0][3]) * this.RawComponents[1][1])) * d; Result.RawComponents[2][3] = (((((-((this.RawComponents[0][0] * this.RawComponents[1][1]) * this.RawComponents[2][3]) + ((this.RawComponents[0][0] * this.RawComponents[1][3]) * this.RawComponents[2][1])) + ((this.RawComponents[1][0] * this.RawComponents[0][1]) * this.RawComponents[2][3])) - ((this.RawComponents[1][0] * this.RawComponents[0][3]) * this.RawComponents[2][1])) - ((this.RawComponents[2][0] * this.RawComponents[0][1]) * this.RawComponents[1][3])) + ((this.RawComponents[2][0] * this.RawComponents[0][3]) * this.RawComponents[1][1])) * d; Result.RawComponents[3][0] = t12 * d; Result.RawComponents[3][1] = (((((((this.RawComponents[0][0] * this.RawComponents[2][1]) * this.RawComponents[3][2]) - ((this.RawComponents[0][0] * this.RawComponents[2][2]) * this.RawComponents[3][1])) - ((this.RawComponents[2][0] * this.RawComponents[0][1]) * this.RawComponents[3][2])) + ((this.RawComponents[2][0] * this.RawComponents[0][2]) * this.RawComponents[3][1])) + ((this.RawComponents[3][0] * this.RawComponents[0][1]) * this.RawComponents[2][2])) - ((this.RawComponents[3][0] * this.RawComponents[0][2]) * this.RawComponents[2][1])) * d; Result.RawComponents[3][2] = (((((-((this.RawComponents[0][0] * this.RawComponents[1][1]) * this.RawComponents[3][2]) + ((this.RawComponents[0][0] * this.RawComponents[1][2]) * this.RawComponents[3][1])) + ((this.RawComponents[1][0] * this.RawComponents[0][1]) * this.RawComponents[3][2])) - ((this.RawComponents[1][0] * this.RawComponents[0][2]) * this.RawComponents[3][1])) - ((this.RawComponents[3][0] * this.RawComponents[0][1]) * this.RawComponents[1][2])) + ((this.RawComponents[3][0] * this.RawComponents[0][2]) * this.RawComponents[1][1])) * d; Result.RawComponents[3][3] = (((((((this.RawComponents[0][0] * this.RawComponents[1][1]) * this.RawComponents[2][2]) - ((this.RawComponents[0][0] * this.RawComponents[1][2]) * this.RawComponents[2][1])) - ((this.RawComponents[1][0] * this.RawComponents[0][1]) * this.RawComponents[2][2])) + ((this.RawComponents[1][0] * this.RawComponents[0][2]) * this.RawComponents[2][1])) + ((this.RawComponents[2][0] * this.RawComponents[0][1]) * this.RawComponents[1][2])) - ((this.RawComponents[2][0] * this.RawComponents[0][2]) * this.RawComponents[1][1])) * d; }; return Result; }; this.CopyList = function () { var Result = []; var x = 0; var y = 0; var list = null; list = new Array(); for (x = 0; x <= 3; x++) for (y = 0; y <= 3; y++) list.push(this.RawComponents[x][y]); Result = list; return Result; }; }); $mod.$init = function () { $impl.Matrix4x4Identity = $mod.TMat4.$create("Identity"); }; },null,function () { "use strict"; var $mod = this; var $impl = $mod.$impl; $impl.PI = 3.14159265359; $impl.DEG2RAD = 3.14159265359 / 180.0; $impl.Matrix4x4Identity = null; }); rtl.module("GLUtils",["System","Mat4","GLTypes","browserconsole","Web","webgl","JS","math","SysUtils"],function () { "use strict"; var $mod = this; var $impl = $mod.$impl; rtl.createClass($mod,"TShader",pas.System.TObject,function () { this.$init = function () { pas.System.TObject.$init.call(this); this.gl = null; this.vertexShader = null; this.fragmentShader = null; this.programID = null; }; this.$final = function () { this.gl = undefined; this.vertexShader = undefined; this.fragmentShader = undefined; this.programID = undefined; pas.System.TObject.$final.call(this); }; this.Create$1 = function (context, vertexShaderSource, fragmentShaderSource) { this.gl = context; this.vertexShader = this.CreateShader(this.gl.VERTEX_SHADER,vertexShaderSource); this.fragmentShader = this.CreateShader(this.gl.FRAGMENT_SHADER,fragmentShaderSource); }; this.Compile = function () { this.programID = this.gl.createProgram(); this.gl.attachShader(this.programID,this.vertexShader); this.gl.attachShader(this.programID,this.fragmentShader); }; this.Link = function () { this.gl.linkProgram(this.programID); if (!this.gl.getProgramParameter(this.programID,this.gl.LINK_STATUS)) { $impl.Fatal(this.gl.getProgramInfoLog(this.programID)); }; }; this.Use = function () { this.gl.useProgram(this.programID); }; this.BindAttribLocation = function (index, name) { this.gl.bindAttribLocation(this.programID,index,name); }; this.SetUniformMat4 = function (name, value) { var list = []; list = value.CopyList(); this.gl.uniformMatrix4fv(this.GetUniformLocation(name),false,list); $mod.GLFatal(this.gl,"gl.uniformMatrix4fv"); }; this.SetUniformVec3 = function (name, value) { this.gl.uniform3f(this.GetUniformLocation(name),value.x,value.y,value.z); $mod.GLFatal(this.gl,"gl.uniform3fv"); }; this.SetUniformFloat = function (name, value) { this.gl.uniform1f(this.GetUniformLocation(name),value); $mod.GLFatal(this.gl,"gl.uniform1f"); }; this.GetUniformLocation = function (name) { var Result = null; Result = this.gl.getUniformLocation(this.programID,name); $mod.GLFatal(this.gl,"gl.getUniformLocation"); return Result; }; this.CreateShader = function (theType, source) { var Result = null; var shader = null; shader = this.gl.createShader(theType); if (shader === null) $impl.Fatal("create shader failed"); this.gl.shaderSource(shader,source); this.gl.compileShader(shader); if (this.gl.getShaderParameter(shader,this.gl.COMPILE_STATUS)) { return shader; } else { $impl.Fatal$1(this.gl.getShaderInfoLog(shader)); }; return Result; }; }); this.TModelData = function (s) { if (s) { this.verticies = s.verticies; this.indicies = s.indicies; this.floatsPerVertex = s.floatsPerVertex; } else { this.verticies = null; this.indicies = null; this.floatsPerVertex = 0; }; this.$equal = function (b) { return (this.verticies === b.verticies) && ((this.indicies === b.indicies) && (this.floatsPerVertex === b.floatsPerVertex)); }; }; this.kModelVertexFloats = (3 + 2) + 3; this.TModelVertex = function (s) { if (s) { this.pos = new pas.GLTypes.TVec3(s.pos); this.texCoord = new pas.GLTypes.TVec2(s.texCoord); this.normal = new pas.GLTypes.TVec3(s.normal); } else { this.pos = new pas.GLTypes.TVec3(); this.texCoord = new pas.GLTypes.TVec2(); this.normal = new pas.GLTypes.TVec3(); }; this.$equal = function (b) { return this.pos.$equal(b.pos) && (this.texCoord.$equal(b.texCoord) && this.normal.$equal(b.normal)); }; }; this.ModelVertexAddToArray = function (vertex, list) { list.push(vertex.pos.x); list.push(vertex.pos.y); list.push(vertex.pos.z); list.push(vertex.texCoord.x); list.push(vertex.texCoord.y); list.push(vertex.normal.x); list.push(vertex.normal.y); list.push(vertex.normal.z); }; rtl.createClass($mod,"TModel",pas.System.TObject,function () { this.$init = function () { pas.System.TObject.$init.call(this); this.gl = null; this.data = new $mod.TModelData(); this.vertexBuffer = null; this.indexBuffer = null; }; this.$final = function () { this.gl = undefined; this.data = undefined; this.vertexBuffer = undefined; this.indexBuffer = undefined; pas.System.TObject.$final.call(this); }; this.Create$1 = function (context, modelData) { this.gl = context; this.data = new $mod.TModelData(modelData); this.Load(); }; this.Draw = function () { this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer); this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer); this.EnableAttributes(); this.gl.drawElements(this.gl.TRIANGLES,this.data.indicies.length,this.gl.UNSIGNED_SHORT,0); this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null); this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null); }; this.EnableAttributes = function () { var offset = 0; var stride = 0; offset = 0; stride = this.data.floatsPerVertex * $mod.GLSizeof(WebGLRenderingContext.FLOAT); this.gl.enableVertexAttribArray(0); this.gl.vertexAttribPointer(0,3,this.gl.FLOAT,false,stride,offset); offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 3; this.gl.enableVertexAttribArray(1); this.gl.vertexAttribPointer(1,2,this.gl.FLOAT,false,stride,offset); offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 2; this.gl.enableVertexAttribArray(2); this.gl.vertexAttribPointer(2,3,this.gl.FLOAT,false,stride,offset); offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 3; }; this.Load = function () { this.indexBuffer = this.gl.createBuffer(); this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer); this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.data.indicies,this.gl.STATIC_DRAW); this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null); this.vertexBuffer = this.gl.createBuffer(); this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer); this.gl.bufferData(this.gl.ARRAY_BUFFER,this.data.verticies,this.gl.STATIC_DRAW); this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null); }; }); this.GLSizeof = function (glType) { var Result = 0; var $tmp1 = glType; if (($tmp1 === WebGLRenderingContext.UNSIGNED_BYTE) || ($tmp1 === WebGLRenderingContext.BYTE)) { Result = 1} else if (($tmp1 === WebGLRenderingContext.SHORT) || ($tmp1 === WebGLRenderingContext.UNSIGNED_SHORT)) { Result = 2} else if (($tmp1 === WebGLRenderingContext.INT) || ($tmp1 === WebGLRenderingContext.UNSIGNED_INT)) { Result = 4} else if ($tmp1 === WebGLRenderingContext.FLOAT) { Result = 4} else { $impl.Fatal("GLSizeof type is invalid."); }; return Result; }; this.GLFatal = function (gl, messageString) { var error = 0; error = gl.getError(); if (error !== WebGLRenderingContext.NO_ERROR) { var $tmp1 = error; if ($tmp1 === WebGLRenderingContext.INVALID_VALUE) { messageString = messageString + " (GL_INVALID_VALUE)"} else if ($tmp1 === WebGLRenderingContext.INVALID_OPERATION) { messageString = messageString + " (GL_INVALID_OPERATION)"} else if ($tmp1 === WebGLRenderingContext.INVALID_ENUM) { messageString = messageString + " (GL_INVALID_ENUM)"} else { messageString = (messageString + " ") + pas.SysUtils.IntToStr(error); }; $impl.Fatal(messageString); }; }; },null,function () { "use strict"; var $mod = this; var $impl = $mod.$impl; $impl.Fatal = function (messageString) { pas.System.Writeln("*** FATAL: ",messageString); throw pas.SysUtils.Exception.$create("Create$1",["FATAL"]); }; $impl.Fatal$1 = function (messageString) { pas.System.Writeln("*** FATAL: ",messageString); throw pas.SysUtils.Exception.$create("Create$1",["FATAL"]); }; }); rtl.module("Terrain",["System","Noise","Matrix","GLTypes","GLUtils","webgl","JS","math"],function () { "use strict"; var $mod = this; rtl.createClass($mod,"TTerrain",pas.System.TObject,function () { this.$init = function () { pas.System.TObject.$init.call(this); this.noise$1 = null; this.gl = null; this.noiseOffset = new pas.GLTypes.TVec2(); this.terrainSize = 0; this.terrainResolution = 0; this.heights = null; this.model = null; }; this.$final = function () { this.noise$1 = undefined; this.gl = undefined; this.noiseOffset = undefined; this.heights = undefined; this.model = undefined; pas.System.TObject.$final.call(this); }; this.Create$2 = function (context, inNoise, size, resolution, offset) { this.gl = context; this.noise$1 = inNoise; this.noiseOffset = new pas.GLTypes.TVec2(offset); this.terrainSize = size; this.terrainResolution = resolution; }; this.GetHeightAtPoint = function (x, y) { var Result = 0.0; Result = rtl.getNumber(this.heights.GetValue(x,y)); return Result; }; this.GetWidth = function () { var Result = 0; Result = this.heights.GetWidth(); return Result; }; this.GetHeight = function () { var Result = 0; Result = this.heights.GetHeight(); return Result; }; this.Draw = function () { this.model.Draw(); }; this.Generate = function () { var vertex = new pas.GLUtils.TModelVertex(); var topLeft = 0; var topRight = 0; var bottomLeft = 0; var bottomRight = 0; var x = 0; var y = 0; var gz = 0; var gx = 0; var verticies = null; var indicies = null; var data = new pas.GLUtils.TModelData(); if (this.noise$1 === null) this.noise$1 = pas.Noise.TNoise.$create("Create$2",[pas.Noise.RandomNoiseSeed(1).slice(0)]); this.heights = pas.Matrix.TMatrix.$create("Create$1",[this.terrainResolution,this.terrainResolution]); verticies = new Array(); indicies = new Array(); for (var $l1 = 0, $end2 = this.heights.GetWidth() - 1; $l1 <= $end2; $l1++) { y = $l1; for (var $l3 = 0, $end4 = this.heights.GetHeight() - 1; $l3 <= $end4; $l3++) { x = $l3; vertex.pos.x = (x / (this.heights.GetWidth() - 1)) * this.terrainSize; vertex.pos.y = this.GetHeightForVertex(x,y,pas.System.Trunc(this.noiseOffset.x) + x,pas.System.Trunc(this.noiseOffset.y) + y); vertex.pos.z = (y / (this.heights.GetHeight() - 1)) * this.terrainSize; this.heights.SetValue(x,y,vertex.pos.y); vertex.normal = new pas.GLTypes.TVec3(this.CalculateNormal(x,y,pas.System.Trunc(this.noiseOffset.x) + x,pas.System.Trunc(this.noiseOffset.y) + y)); vertex.texCoord.x = x / (this.heights.GetWidth() - 1); vertex.texCoord.y = y / (this.heights.GetHeight() - 1); pas.GLUtils.ModelVertexAddToArray(new pas.GLUtils.TModelVertex(vertex),verticies); }; }; for (var $l5 = 0, $end6 = this.heights.GetWidth() - 2; $l5 <= $end6; $l5++) { gz = $l5; for (var $l7 = 0, $end8 = this.heights.GetHeight() - 2; $l7 <= $end8; $l7++) { gx = $l7; topLeft = (gz * this.heights.GetWidth()) + gx; topRight = topLeft + 1; bottomLeft = ((gz + 1) * this.heights.GetWidth()) + gx; bottomRight = bottomLeft + 1; indicies.push(topLeft); indicies.push(bottomLeft); indicies.push(topRight); indicies.push(topRight); indicies.push(bottomLeft); indicies.push(bottomRight); }; }; data.verticies = new Float32Array(verticies); data.indicies = new Uint16Array(indicies); data.floatsPerVertex = 8; this.model = pas.GLUtils.TModel.$create("Create$1",[this.gl,new pas.GLUtils.TModelData(data)]); }; this.GetHeightForVertex = function (localX, localY, x, y) { var Result = 0.0; Result = this.noise$1.GetNoise(x,y,this.heights.GetWidth(),this.heights.GetHeight(),4,3); Result = Math.pow(Result,5); Result = (Result * 20) - 6; return Result; }; this.CalculateNormal = function (localX, localY, x, y) { var Result = new pas.GLTypes.TVec3(); var heightL = 0.0; var heightR = 0.0; var heightD = 0.0; var heightU = 0.0; heightL = this.GetHeightForVertex(localX,localY,x - 1,y); heightR = this.GetHeightForVertex(localX,localY,x + 1,y); heightD = this.GetHeightForVertex(localX,localY,x,y - 1); heightU = this.GetHeightForVertex(localX,localY,x,y + 1); Result = new pas.GLTypes.TVec3(pas.GLTypes.V3(heightL - heightR,2.0,heightD - heightU)); Result = new pas.GLTypes.TVec3(pas.GLTypes.Normalize(new pas.GLTypes.TVec3(Result))); return Result; }; }); }); rtl.module("program",["System","Terrain","Noise","Mat4","GLUtils","GLTypes","SysUtils","browserconsole","Web","webgl","JS","math"],function () { "use strict"; var $mod = this; this.gl = null; this.shader = null; this.projTransform = null; this.viewTransform = null; this.modelTransform = null; this.debugConsole = null; this.canvasAnimationHandler = 0; this.maps = null; this.camera = new pas.GLTypes.TVec3(); this.lightPosition = new pas.GLTypes.TVec3(); this.terrainNoise = null; this.terrainSize = 64 * 3; this.terrainResolution = 128; this.flySpeed = 1.3; this.visiblity = 4; this.textureLoaded = false; rtl.createClass($mod,"TTilingTerrain",pas.Terrain.TTerrain,function () { this.$init = function () { pas.Terrain.TTerrain.$init.call(this); this.neighbor = null; }; this.$final = function () { this.neighbor = undefined; pas.Terrain.TTerrain.$final.call(this); }; this.GetHeightForVertex = function (localX, localY, x, y) { var Result = 0.0; if ((localY === 0) && (this.neighbor !== null)) { Result = this.neighbor.GetHeightAtPoint(localX,(localY + this.neighbor.GetWidth()) - 1)} else { Result = this.noise$1.GetNoise(x,y,this.GetWidth(),this.GetHeight(),6,3); Result = Math.pow(Result,9) * 60; }; return Result; }; }); this.DrawCanvas = function () { var terrainCoord = new pas.GLTypes.TVec3(); var startIndex = 0; var endIndex = 0; var i = 0; var map = null; $mod.gl.clear($mod.gl.COLOR_BUFFER_BIT + $mod.gl.DEPTH_BUFFER_BIT); $mod.viewTransform = pas.Mat4.TMat4.$create("Identity"); $mod.viewTransform = $mod.viewTransform.Multiply(pas.Mat4.TMat4.$create("Translate",[$mod.camera.x,$mod.camera.y,$mod.camera.z])); $mod.shader.SetUniformMat4("viewTransform",$mod.viewTransform); $mod.shader.SetUniformMat4("inverseViewTransform",$mod.viewTransform.Inverse()); $mod.lightPosition.z += $mod.flySpeed; $mod.shader.SetUniformVec3("lightPosition",new pas.GLTypes.TVec3($mod.lightPosition)); $mod.camera.z -= $mod.flySpeed; $mod.camera.y = -($mod.terrainSize / 4) + (Math.sin($mod.camera.z / $mod.terrainSize) * 14); $mod.camera.x = -($mod.terrainSize / 2) + (Math.cos($mod.camera.z / $mod.terrainSize) * 20); terrainCoord = new pas.GLTypes.TVec3(pas.GLTypes.Divide(new pas.GLTypes.TVec3($mod.camera),$mod.terrainSize)); endIndex = pas.System.Trunc(Math.abs(terrainCoord.z)); startIndex = endIndex - $mod.visiblity; if (startIndex < 0) startIndex = 0; for (var $l1 = startIndex, $end2 = endIndex; $l1 <= $end2; $l1++) { i = $l1; if (($mod.maps.length === 0) || (($mod.maps.length === i) && ($mod.maps[i] == null))) { map = $mod.TTilingTerrain.$create("Create$2",[$mod.gl,$mod.terrainNoise,$mod.terrainSize,$mod.terrainResolution,new pas.GLTypes.TVec2(pas.GLTypes.V2(0,$mod.terrainSize * i))]); if ((i - 1) >= 0) map.neighbor = rtl.getObject($mod.maps[i - 1]); map.Generate(); $mod.maps.push(map); if ((startIndex - 1) >= 0) $mod.maps[startIndex - 1] = null; }; map = rtl.getObject($mod.maps[i]); $mod.modelTransform = pas.Mat4.TMat4.$create("Identity"); $mod.modelTransform = $mod.modelTransform.Multiply(pas.Mat4.TMat4.$create("Translate",[0,0,$mod.terrainSize * i])); $mod.shader.SetUniformMat4("modelTransform",$mod.modelTransform); map.Draw(); }; }; this.AnimateCanvas = function (time) { if ($mod.textureLoaded) $mod.DrawCanvas(); if ($mod.canvasAnimationHandler !== 0) $mod.canvasAnimationHandler = window.requestAnimationFrame($mod.AnimateCanvas); }; this.StartAnimatingCanvas = function () { $mod.canvasAnimationHandler = window.requestAnimationFrame($mod.AnimateCanvas); }; this.LoadedTexture = function (event) { var Result = false; var texture = null; texture = $mod.gl.createTexture(); $mod.gl.bindTexture($mod.gl.TEXTURE_2D,texture); $mod.gl.texParameteri($mod.gl.TEXTURE_2D,$mod.gl.TEXTURE_WRAP_S,$mod.gl.CLAMP_TO_EDGE); $mod.gl.texParameteri($mod.gl.TEXTURE_2D,$mod.gl.TEXTURE_WRAP_T,$mod.gl.CLAMP_TO_EDGE); $mod.gl.texParameteri($mod.gl.TEXTURE_2D,$mod.gl.TEXTURE_MIN_FILTER,$mod.gl.LINEAR); $mod.gl.texParameteri($mod.gl.TEXTURE_2D,$mod.gl.TEXTURE_MAG_FILTER,$mod.gl.LINEAR); $mod.gl.texImage2D($mod.gl.TEXTURE_2D,0,$mod.gl.RGBA,$mod.gl.RGBA,$mod.gl.UNSIGNED_BYTE,rtl.getObject(event.target)); $mod.textureLoaded = true; Result = true; return Result; }; this.canvas = null; this.vertexShaderSource = ""; this.fragmentShaderSource = ""; this.img = null; $mod.$main = function () { $mod.debugConsole = document.getElementById("debug-console"); $mod.canvas = document.createElement("canvas"); $mod.canvas.width = 800; $mod.canvas.height = 600; document.body.appendChild($mod.canvas); $mod.gl = $mod.canvas.getContext("webgl"); if ($mod.gl === null) { pas.System.Writeln("failed to load webgl!"); return; }; $mod.vertexShaderSource = document.getElementById("vertex.glsl").textContent; $mod.fragmentShaderSource = document.getElementById("fragment.glsl").textContent; $mod.shader = pas.GLUtils.TShader.$create("Create$1",[$mod.gl,$mod.vertexShaderSource,$mod.fragmentShaderSource]); $mod.shader.Compile(); $mod.shader.BindAttribLocation(0,"in_position"); $mod.shader.BindAttribLocation(1,"in_texCoord"); $mod.shader.BindAttribLocation(2,"in_normal"); $mod.shader.Link(); $mod.shader.Use(); $mod.gl.clearColor(0.9,0.9,0.9,1); $mod.gl.viewport(0,0,$mod.canvas.width,$mod.canvas.height); $mod.gl.enable($mod.gl.DEPTH_TEST); $mod.gl.enable($mod.gl.BLEND); $mod.gl.enable($mod.gl.CULL_FACE); $mod.gl.cullFace($mod.gl.BACK); $mod.projTransform = pas.Mat4.TMat4.$create("Perspective",[60.0,$mod.canvas.width / $mod.canvas.height,0.1,2000]); $mod.shader.SetUniformMat4("projTransform",$mod.projTransform); $mod.lightPosition = new pas.GLTypes.TVec3(pas.GLTypes.V3(0,$mod.terrainSize / 2,-($mod.terrainSize / 2))); $mod.shader.SetUniformVec3("lightPosition",new pas.GLTypes.TVec3($mod.lightPosition)); $mod.shader.SetUniformVec3("lightColor",new pas.GLTypes.TVec3(pas.GLTypes.V3(1,1,1))); $mod.shader.SetUniformFloat("shineDamper",1000); $mod.shader.SetUniformFloat("reflectivity",1); $mod.gl.clear($mod.gl.COLOR_BUFFER_BIT + $mod.gl.DEPTH_BUFFER_BIT); $mod.camera.x = -($mod.terrainSize / 2); $mod.camera.y = -($mod.terrainSize / 4); $mod.camera.z = -($mod.terrainSize / 2); $mod.img = document.createElement("IMG"); $mod.img.setAttribute("height","512"); $mod.img.setAttribute("width","512"); $mod.img.setAttribute("crossOrigin","anonymous"); $mod.img.setAttribute("src","res\/ground.jpg"); $mod.img.onload = $mod.LoadedTexture; $mod.terrainNoise = pas.Noise.TNoise.$create("Create$2",[pas.Noise.RandomNoiseSeed(1).slice(0)]); $mod.maps = new Array(); $mod.StartAnimatingCanvas(); }; });