Pas2JS_WebGL_OBJ.js 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666
  1. var pas = {};
  2. var rtl = {
  3. quiet: false,
  4. debug_load_units: false,
  5. debug_rtti: false,
  6. debug: function(){
  7. if (rtl.quiet || !console || !console.log) return;
  8. console.log(arguments);
  9. },
  10. error: function(s){
  11. rtl.debug('Error: ',s);
  12. throw s;
  13. },
  14. warn: function(s){
  15. rtl.debug('Warn: ',s);
  16. },
  17. hasString: function(s){
  18. return rtl.isString(s) && (s.length>0);
  19. },
  20. isArray: function(a) {
  21. return Array.isArray(a);
  22. },
  23. isFunction: function(f){
  24. return typeof(f)==="function";
  25. },
  26. isModule: function(m){
  27. return rtl.isObject(m) && rtl.hasString(m.$name) && (pas[m.$name]===m);
  28. },
  29. isImplementation: function(m){
  30. return rtl.isObject(m) && rtl.isModule(m.$module) && (m.$module.$impl===m);
  31. },
  32. isNumber: function(n){
  33. return typeof(n)==="number";
  34. },
  35. isObject: function(o){
  36. var s=typeof(o);
  37. return (typeof(o)==="object") && (o!=null);
  38. },
  39. isString: function(s){
  40. return typeof(s)==="string";
  41. },
  42. getNumber: function(n){
  43. return typeof(n)==="number"?n:NaN;
  44. },
  45. getChar: function(c){
  46. return ((typeof(c)==="string") && (c.length===1)) ? c : "";
  47. },
  48. getObject: function(o){
  49. return ((typeof(o)==="object") || (typeof(o)==='function')) ? o : null;
  50. },
  51. isPasClass: function(type){
  52. return (rtl.isObject(type) && type.hasOwnProperty('$classname') && rtl.isObject(type.$module));
  53. },
  54. isPasClassInstance: function(type){
  55. return (rtl.isObject(type) && rtl.isPasClass(type.$class));
  56. },
  57. hexStr: function(n,digits){
  58. return ("000000000000000"+n.toString(16).toUpperCase()).slice(-digits);
  59. },
  60. m_loading: 0,
  61. m_loading_intf: 1,
  62. m_intf_loaded: 2,
  63. m_loading_impl: 3, // loading all used unit
  64. m_initializing: 4, // running initialization
  65. m_initialized: 5,
  66. module: function(module_name, intfuseslist, intfcode, impluseslist, implcode){
  67. if (rtl.debug_load_units) rtl.debug('rtl.module name="'+module_name+'" intfuses='+intfuseslist+' impluses='+impluseslist+' hasimplcode='+rtl.isFunction(implcode));
  68. if (!rtl.hasString(module_name)) rtl.error('invalid module name "'+module_name+'"');
  69. if (!rtl.isArray(intfuseslist)) rtl.error('invalid interface useslist of "'+module_name+'"');
  70. if (!rtl.isFunction(intfcode)) rtl.error('invalid interface code of "'+module_name+'"');
  71. if (!(impluseslist==undefined) && !rtl.isArray(impluseslist)) rtl.error('invalid implementation useslist of "'+module_name+'"');
  72. if (!(implcode==undefined) && !rtl.isFunction(implcode)) rtl.error('invalid implementation code of "'+module_name+'"');
  73. if (pas[module_name])
  74. rtl.error('module "'+module_name+'" is already registered');
  75. var module = pas[module_name] = {
  76. $name: module_name,
  77. $intfuseslist: intfuseslist,
  78. $impluseslist: impluseslist,
  79. $state: rtl.m_loading,
  80. $intfcode: intfcode,
  81. $implcode: implcode,
  82. $impl: null,
  83. $rtti: Object.create(rtl.tSectionRTTI)
  84. };
  85. module.$rtti.$module = module;
  86. if (implcode) module.$impl = {
  87. $module: module,
  88. $rtti: module.$rtti
  89. };
  90. },
  91. exitcode: 0,
  92. run: function(module_name){
  93. function doRun(){
  94. if (!rtl.hasString(module_name)) module_name='program';
  95. if (rtl.debug_load_units) rtl.debug('rtl.run module="'+module_name+'"');
  96. rtl.initRTTI();
  97. var module = pas[module_name];
  98. if (!module) rtl.error('rtl.run module "'+module_name+'" missing');
  99. rtl.loadintf(module);
  100. rtl.loadimpl(module);
  101. if (module_name=='program'){
  102. if (rtl.debug_load_units) rtl.debug('running $main');
  103. var r = pas.program.$main();
  104. if (rtl.isNumber(r)) rtl.exitcode = r;
  105. }
  106. }
  107. if (rtl.showUncaughtExceptions) {
  108. try{
  109. doRun();
  110. } catch(re) {
  111. var errMsg = re.hasOwnProperty('$class') ? re.$class.$classname : '';
  112. errMsg += ((errMsg) ? ': ' : '') + (re.hasOwnProperty('fMessage') ? re.fMessage : re);
  113. alert('Uncaught Exception : '+errMsg);
  114. rtl.exitCode = 216;
  115. }
  116. } else {
  117. doRun();
  118. }
  119. return rtl.exitcode;
  120. },
  121. loadintf: function(module){
  122. if (module.$state>rtl.m_loading_intf) return; // already finished
  123. if (rtl.debug_load_units) rtl.debug('loadintf: "'+module.$name+'"');
  124. if (module.$state===rtl.m_loading_intf)
  125. rtl.error('unit cycle detected "'+module.$name+'"');
  126. module.$state=rtl.m_loading_intf;
  127. // load interfaces of interface useslist
  128. rtl.loaduseslist(module,module.$intfuseslist,rtl.loadintf);
  129. // run interface
  130. if (rtl.debug_load_units) rtl.debug('loadintf: run intf of "'+module.$name+'"');
  131. module.$intfcode(module.$intfuseslist);
  132. // success
  133. module.$state=rtl.m_intf_loaded;
  134. // Note: units only used in implementations are not yet loaded (not even their interfaces)
  135. },
  136. loaduseslist: function(module,useslist,f){
  137. if (useslist==undefined) return;
  138. for (var i in useslist){
  139. var unitname=useslist[i];
  140. if (rtl.debug_load_units) rtl.debug('loaduseslist of "'+module.$name+'" uses="'+unitname+'"');
  141. if (pas[unitname]==undefined)
  142. rtl.error('module "'+module.$name+'" misses "'+unitname+'"');
  143. f(pas[unitname]);
  144. }
  145. },
  146. loadimpl: function(module){
  147. if (module.$state>=rtl.m_loading_impl) return; // already processing
  148. if (module.$state<rtl.m_intf_loaded) rtl.error('loadimpl: interface not loaded of "'+module.$name+'"');
  149. if (rtl.debug_load_units) rtl.debug('loadimpl: load uses of "'+module.$name+'"');
  150. module.$state=rtl.m_loading_impl;
  151. // load interfaces of implementation useslist
  152. rtl.loaduseslist(module,module.$impluseslist,rtl.loadintf);
  153. // load implementation of interfaces useslist
  154. rtl.loaduseslist(module,module.$intfuseslist,rtl.loadimpl);
  155. // load implementation of implementation useslist
  156. rtl.loaduseslist(module,module.$impluseslist,rtl.loadimpl);
  157. // Note: At this point all interfaces used by this unit are loaded. If
  158. // there are implementation uses cycles some used units might not yet be
  159. // initialized. This is by design.
  160. // run implementation
  161. if (rtl.debug_load_units) rtl.debug('loadimpl: run impl of "'+module.$name+'"');
  162. if (rtl.isFunction(module.$implcode)) module.$implcode(module.$impluseslist);
  163. // run initialization
  164. if (rtl.debug_load_units) rtl.debug('loadimpl: run init of "'+module.$name+'"');
  165. module.$state=rtl.m_initializing;
  166. if (rtl.isFunction(module.$init)) module.$init();
  167. // unit initialized
  168. module.$state=rtl.m_initialized;
  169. },
  170. createCallback: function(scope, fn){
  171. var cb;
  172. if (typeof(fn)==='string'){
  173. cb = function(){
  174. return scope[fn].apply(scope,arguments);
  175. };
  176. } else {
  177. cb = function(){
  178. return fn.apply(scope,arguments);
  179. };
  180. };
  181. cb.scope = scope;
  182. cb.fn = fn;
  183. return cb;
  184. },
  185. cloneCallback: function(cb){
  186. return rtl.createCallback(cb.scope,cb.fn);
  187. },
  188. eqCallback: function(a,b){
  189. // can be a function or a function wrapper
  190. if (a==b){
  191. return true;
  192. } else {
  193. return (a!=null) && (b!=null) && (a.fn) && (a.scope===b.scope) && (a.fn==b.fn);
  194. }
  195. },
  196. initClass: function(c,parent,name,initfn){
  197. parent[name] = c;
  198. c.$classname = name;
  199. if ((parent.$module) && (parent.$module.$impl===parent)) parent=parent.$module;
  200. c.$parent = parent;
  201. c.$fullname = parent.$name+'.'+name;
  202. if (rtl.isModule(parent)){
  203. c.$module = parent;
  204. c.$name = name;
  205. } else {
  206. c.$module = parent.$module;
  207. c.$name = parent.name+'.'+name;
  208. };
  209. // rtti
  210. if (rtl.debug_rtti) rtl.debug('initClass '+c.$fullname);
  211. var t = c.$module.$rtti.$Class(c.$name,{ "class": c, module: parent });
  212. c.$rtti = t;
  213. if (rtl.isObject(c.$ancestor)) t.ancestor = c.$ancestor.$rtti;
  214. if (!t.ancestor) t.ancestor = null;
  215. // init members
  216. initfn.call(c);
  217. },
  218. createClass: function(parent,name,ancestor,initfn){
  219. // create a normal class,
  220. // ancestor must be null or a normal class,
  221. // the root ancestor can be an external class
  222. var c = null;
  223. if (ancestor != null){
  224. c = Object.create(ancestor);
  225. c.$ancestor = ancestor;
  226. // Note:
  227. // if root is an "object" then c.$ancestor === Object.getPrototypeOf(c)
  228. // if root is a "function" then c.$ancestor === c.__proto__, Object.getPrototypeOf(c) returns the root
  229. } else {
  230. c = {};
  231. c.$create = function(fnname,args){
  232. if (args == undefined) args = [];
  233. var o = Object.create(this);
  234. o.$class = this; // Note: o.$class === Object.getPrototypeOf(o)
  235. o.$init();
  236. try{
  237. o[fnname].apply(o,args);
  238. o.AfterConstruction();
  239. } catch($e){
  240. o.$destroy;
  241. throw $e;
  242. }
  243. return o;
  244. };
  245. c.$destroy = function(fnname){
  246. this.BeforeDestruction();
  247. this[fnname]();
  248. this.$final;
  249. };
  250. };
  251. rtl.initClass(c,parent,name,initfn);
  252. },
  253. createClassExt: function(parent,name,ancestor,newinstancefnname,initfn){
  254. // Create a class using an external ancestor.
  255. // If newinstancefnname is given, use that function to create the new object.
  256. // If exist call BeforeDestruction and AfterConstruction.
  257. var c = null;
  258. c = Object.create(ancestor);
  259. c.$create = function(fnname,args){
  260. if (args == undefined) args = [];
  261. var o = null;
  262. if (newinstancefnname.length>0){
  263. o = this[newinstancefnname](fnname,args);
  264. } else {
  265. o = Object.create(this);
  266. }
  267. o.$class = this; // Note: o.$class === Object.getPrototypeOf(o)
  268. o.$init();
  269. try{
  270. o[fnname].apply(o,args);
  271. if (o.AfterConstruction) o.AfterConstruction();
  272. } catch($e){
  273. o.$destroy;
  274. throw $e;
  275. }
  276. return o;
  277. };
  278. c.$destroy = function(fnname){
  279. if (this.BeforeDestruction) this.BeforeDestruction();
  280. this[fnname]();
  281. this.$final;
  282. };
  283. rtl.initClass(c,parent,name,initfn);
  284. },
  285. tObjectDestroy: "Destroy",
  286. free: function(obj,name){
  287. if (obj[name]==null) return;
  288. obj[name].$destroy(rtl.tObjectDestroy);
  289. obj[name]=null;
  290. },
  291. freeLoc: function(obj){
  292. if (obj==null) return;
  293. obj.$destroy(rtl.tObjectDestroy);
  294. return null;
  295. },
  296. is: function(instance,type){
  297. return type.isPrototypeOf(instance) || (instance===type);
  298. },
  299. isExt: function(instance,type,mode){
  300. // mode===1 means instance must be a Pascal class instance
  301. // mode===2 means instance must be a Pascal class
  302. // Notes:
  303. // isPrototypeOf and instanceof return false on equal
  304. // isPrototypeOf does not work for Date.isPrototypeOf(new Date())
  305. // so if isPrototypeOf is false test with instanceof
  306. // instanceof needs a function on right side
  307. if (instance == null) return false; // Note: ==null checks for undefined too
  308. if ((typeof(type) !== 'object') && (typeof(type) !== 'function')) return false;
  309. if (instance === type){
  310. if (mode===1) return false;
  311. if (mode===2) return rtl.isPasClass(instance);
  312. return true;
  313. }
  314. if (type.isPrototypeOf && type.isPrototypeOf(instance)){
  315. if (mode===1) return rtl.isPasClassInstance(instance);
  316. if (mode===2) return rtl.isPasClass(instance);
  317. return true;
  318. }
  319. if ((typeof type == 'function') && (instance instanceof type)) return true;
  320. return false;
  321. },
  322. Exception: null,
  323. EInvalidCast: null,
  324. EAbstractError: null,
  325. ERangeError: null,
  326. raiseE: function(typename){
  327. var t = rtl[typename];
  328. if (t==null){
  329. var mod = pas.SysUtils;
  330. if (!mod) mod = pas.sysutils;
  331. if (mod){
  332. t = mod[typename];
  333. if (!t) t = mod[typename.toLowerCase()];
  334. if (!t) t = mod['Exception'];
  335. if (!t) t = mod['exception'];
  336. }
  337. }
  338. if (t){
  339. if (t.Create){
  340. throw t.$create("Create");
  341. } else if (t.create){
  342. throw t.$create("create");
  343. }
  344. }
  345. if (typename === "EInvalidCast") throw "invalid type cast";
  346. if (typename === "EAbstractError") throw "Abstract method called";
  347. if (typename === "ERangeError") throw "range error";
  348. throw typename;
  349. },
  350. as: function(instance,type){
  351. if((instance === null) || rtl.is(instance,type)) return instance;
  352. rtl.raiseE("EInvalidCast");
  353. },
  354. asExt: function(instance,type,mode){
  355. if((instance === null) || rtl.isExt(instance,type,mode)) return instance;
  356. rtl.raiseE("EInvalidCast");
  357. },
  358. createInterface: function(module, name, guid, fnnames, ancestor, initfn){
  359. //console.log('createInterface name="'+name+'" guid="'+guid+'" names='+fnnames);
  360. var i = ancestor?Object.create(ancestor):{};
  361. module[name] = i;
  362. i.$module = module;
  363. i.$name = name;
  364. i.$fullname = module.$name+'.'+name;
  365. i.$guid = guid;
  366. i.$guidr = null;
  367. i.$names = fnnames?fnnames:[];
  368. if (rtl.isFunction(initfn)){
  369. // rtti
  370. if (rtl.debug_rtti) rtl.debug('createInterface '+i.$fullname);
  371. var t = i.$module.$rtti.$Interface(name,{ "interface": i, module: module });
  372. i.$rtti = t;
  373. if (ancestor) t.ancestor = ancestor.$rtti;
  374. if (!t.ancestor) t.ancestor = null;
  375. initfn.call(i);
  376. }
  377. return i;
  378. },
  379. strToGUIDR: function(s,g){
  380. var p = 0;
  381. function n(l){
  382. var h = s.substr(p,l);
  383. p+=l;
  384. return parseInt(h,16);
  385. }
  386. p+=1; // skip {
  387. g.D1 = n(8);
  388. p+=1; // skip -
  389. g.D2 = n(4);
  390. p+=1; // skip -
  391. g.D3 = n(4);
  392. p+=1; // skip -
  393. if (!g.D4) g.D4=[];
  394. g.D4[0] = n(2);
  395. g.D4[1] = n(2);
  396. p+=1; // skip -
  397. for(var i=2; i<8; i++) g.D4[i] = n(2);
  398. return g;
  399. },
  400. guidrToStr: function(g){
  401. if (g.$intf) return g.$intf.$guid;
  402. var h = rtl.hexStr;
  403. var s='{'+h(g.D1,8)+'-'+h(g.D2,4)+'-'+h(g.D3,4)+'-'+h(g.D4[0],2)+h(g.D4[1],2)+'-';
  404. for (var i=2; i<8; i++) s+=h(g.D4[i],2);
  405. s+='}';
  406. return s;
  407. },
  408. createTGUID: function(guid){
  409. var TGuid = (pas.System)?pas.System.TGuid:pas.system.tguid;
  410. var g = rtl.strToGUIDR(guid,new TGuid());
  411. return g;
  412. },
  413. getIntfGUIDR: function(intfTypeOrVar){
  414. if (!intfTypeOrVar) return null;
  415. if (!intfTypeOrVar.$guidr){
  416. var g = rtl.createTGUID(intfTypeOrVar.$guid);
  417. if (!intfTypeOrVar.hasOwnProperty('$guid')) intfTypeOrVar = Object.getPrototypeOf(intfTypeOrVar);
  418. g.$intf = intfTypeOrVar;
  419. intfTypeOrVar.$guidr = g;
  420. }
  421. return intfTypeOrVar.$guidr;
  422. },
  423. addIntf: function (aclass, intf, map){
  424. function jmp(fn){
  425. if (typeof(fn)==="function"){
  426. return function(){ return fn.apply(this.$o,arguments); };
  427. } else {
  428. return function(){ rtl.raiseE('EAbstractError'); };
  429. }
  430. }
  431. if(!map) map = {};
  432. var t = intf;
  433. var item = Object.create(t);
  434. aclass.$intfmaps[intf.$guid] = item;
  435. do{
  436. var names = t.$names;
  437. if (!names) break;
  438. for (var i=0; i<names.length; i++){
  439. var intfname = names[i];
  440. var fnname = map[intfname];
  441. if (!fnname) fnname = intfname;
  442. //console.log('addIntf: intftype='+t.$name+' index='+i+' intfname="'+intfname+'" fnname="'+fnname+'" proc='+typeof(fn));
  443. item[intfname] = jmp(aclass[fnname]);
  444. }
  445. t = Object.getPrototypeOf(t);
  446. }while(t!=null);
  447. },
  448. getIntfG: function (obj, guid, query){
  449. if (!obj) return null;
  450. //console.log('getIntfG: obj='+obj.$classname+' guid='+guid+' query='+query);
  451. // search
  452. var maps = obj.$intfmaps;
  453. if (!maps) return null;
  454. var item = maps[guid];
  455. if (!item) return null;
  456. // check delegation
  457. //console.log('getIntfG: obj='+obj.$classname+' guid='+guid+' query='+query+' item='+typeof(item));
  458. if (typeof item === 'function') return item.call(obj); // COM: contains _AddRef
  459. // check cache
  460. var intf = null;
  461. if (obj.$interfaces){
  462. intf = obj.$interfaces[guid];
  463. //console.log('getIntfG: obj='+obj.$classname+' guid='+guid+' cache='+typeof(intf));
  464. }
  465. if (!intf){ // intf can be undefined!
  466. intf = Object.create(item);
  467. intf.$o = obj;
  468. if (!obj.$interfaces) obj.$interfaces = {};
  469. obj.$interfaces[guid] = intf;
  470. }
  471. if (typeof(query)==='object'){
  472. // called by queryIntfT
  473. var o = null;
  474. if (intf.QueryInterface(rtl.getIntfGUIDR(query),
  475. {get:function(){ return o; }, set:function(v){ o=v; }}) === 0){
  476. return o;
  477. } else {
  478. return null;
  479. }
  480. } else if(query===2){
  481. // called by TObject.GetInterfaceByStr
  482. if (intf.$kind === 'com') intf._AddRef();
  483. }
  484. return intf;
  485. },
  486. getIntfT: function(obj,intftype){
  487. return rtl.getIntfG(obj,intftype.$guid);
  488. },
  489. queryIntfT: function(obj,intftype){
  490. return rtl.getIntfG(obj,intftype.$guid,intftype);
  491. },
  492. queryIntfIsT: function(obj,intftype){
  493. var i = rtl.queryIntfG(obj,intftype.$guid);
  494. if (!i) return false;
  495. if (i.$kind === 'com') i._Release();
  496. return true;
  497. },
  498. asIntfT: function (obj,intftype){
  499. var i = rtl.getIntfG(obj,intftype.$guid);
  500. if (i!==null) return i;
  501. rtl.raiseEInvalidCast();
  502. },
  503. intfIsClass: function(intf,classtype){
  504. return (intf!=null) && (rtl.is(intf.$o,classtype));
  505. },
  506. intfAsClass: function(intf,classtype){
  507. if (intf==null) return null;
  508. return rtl.as(intf.$o,classtype);
  509. },
  510. intfToClass: function(intf,classtype){
  511. if ((intf!==null) && rtl.is(intf.$o,classtype)) return intf.$o;
  512. return null;
  513. },
  514. // interface reference counting
  515. intfRefs: { // base object for temporary interface variables
  516. ref: function(id,intf){
  517. // called for temporary interface references needing delayed release
  518. var old = this[id];
  519. //console.log('rtl.intfRefs.ref: id='+id+' old="'+(old?old.$name:'null')+'" intf="'+(intf?intf.$name:'null'));
  520. if (old){
  521. // called again, e.g. in a loop
  522. delete this[id];
  523. old._Release(); // may fail
  524. }
  525. this[id]=intf;
  526. return intf;
  527. },
  528. free: function(){
  529. //console.log('rtl.intfRefs.free...');
  530. for (var id in this){
  531. if (this.hasOwnProperty(id)) this[id]._Release;
  532. }
  533. }
  534. },
  535. createIntfRefs: function(){
  536. //console.log('rtl.createIntfRefs');
  537. return Object.create(rtl.intfRefs);
  538. },
  539. setIntfP: function(path,name,value,skipAddRef){
  540. var old = path[name];
  541. //console.log('rtl.setIntfP path='+path+' name='+name+' old="'+(old?old.$name:'null')+'" value="'+(value?value.$name:'null')+'"');
  542. if (old === value) return;
  543. if (old !== null){
  544. path[name]=null;
  545. old._Release();
  546. }
  547. if (value !== null){
  548. if (!skipAddRef) value._AddRef();
  549. path[name]=value;
  550. }
  551. },
  552. setIntfL: function(old,value,skipAddRef){
  553. //console.log('rtl.setIntfL old="'+(old?old.$name:'null')+'" value="'+(value?value.$name:'null')+'"');
  554. if (old !== value){
  555. if (value!==null){
  556. if (!skipAddRef) value._AddRef();
  557. }
  558. if (old!==null){
  559. old._Release(); // Release after AddRef, to avoid double Release if Release creates an exception
  560. }
  561. } else if (skipAddRef){
  562. if (old!==null){
  563. old._Release(); // value has an AddRef
  564. }
  565. }
  566. return value;
  567. },
  568. _AddRef: function(intf){
  569. //if (intf) console.log('rtl._AddRef intf="'+(intf?intf.$name:'null')+'"');
  570. if (intf) intf._AddRef();
  571. return intf;
  572. },
  573. _Release: function(intf){
  574. //if (intf) console.log('rtl._Release intf="'+(intf?intf.$name:'null')+'"');
  575. if (intf) intf._Release();
  576. return intf;
  577. },
  578. checkMethodCall: function(obj,type){
  579. if (rtl.isObject(obj) && rtl.is(obj,type)) return;
  580. rtl.raiseE("EInvalidCast");
  581. },
  582. rc: function(i,minval,maxval){
  583. // range check integer
  584. if ((Math.floor(i)===i) && (i>=minval) && (i<=maxval)) return i;
  585. rtl.raiseE('ERangeError');
  586. },
  587. rcc: function(c,minval,maxval){
  588. // range check char
  589. if ((typeof(c)==='string') && (c.length===1)){
  590. var i = c.charCodeAt(0);
  591. if ((i>=minval) && (i<=maxval)) return c;
  592. }
  593. rtl.raiseE('ERangeError');
  594. },
  595. rcSetCharAt: function(s,index,c){
  596. // range check setCharAt
  597. if ((typeof(s)!=='string') || (index<0) || (index>=s.length)) rtl.raiseE('ERangeError');
  598. return rtl.setCharAt(s,index,c);
  599. },
  600. rcCharAt: function(s,index){
  601. // range check charAt
  602. if ((typeof(s)!=='string') || (index<0) || (index>=s.length)) rtl.raiseE('ERangeError');
  603. return s.charAt(index);
  604. },
  605. rcArrR: function(arr,index){
  606. // range check read array
  607. if (Array.isArray(arr) && (typeof(index)==='number') && (index>=0) && (index<arr.length)){
  608. if (arguments.length>2){
  609. // arr,index1,index2,...
  610. arr=arr[index];
  611. for (var i=2; i<arguments.length; i++) arr=rtl.rcArrR(arr,arguments[i]);
  612. return arr;
  613. }
  614. return arr[index];
  615. }
  616. rtl.raiseE('ERangeError');
  617. },
  618. rcArrW: function(arr,index,value){
  619. // range check write array
  620. // arr,index1,index2,...,value
  621. for (var i=3; i<arguments.length; i++){
  622. arr=rtl.rcArrR(arr,index);
  623. index=arguments[i-1];
  624. value=arguments[i];
  625. }
  626. if (Array.isArray(arr) && (typeof(index)==='number') && (index>=0) && (index<arr.length)){
  627. return arr[index]=value;
  628. }
  629. rtl.raiseE('ERangeError');
  630. },
  631. length: function(arr){
  632. return (arr == null) ? 0 : arr.length;
  633. },
  634. arraySetLength: function(arr,defaultvalue,newlength){
  635. // multi dim: (arr,defaultvalue,dim1,dim2,...)
  636. if (arr == null) arr = [];
  637. var p = arguments;
  638. function setLength(a,argNo){
  639. var oldlen = a.length;
  640. var newlen = p[argNo];
  641. if (oldlen!==newlength){
  642. a.length = newlength;
  643. if (argNo === p.length-1){
  644. if (rtl.isArray(defaultvalue)){
  645. for (var i=oldlen; i<newlen; i++) a[i]=[]; // nested array
  646. } else if (rtl.isFunction(defaultvalue)){
  647. for (var i=oldlen; i<newlen; i++) a[i]=new defaultvalue(); // e.g. record
  648. } else if (rtl.isObject(defaultvalue)) {
  649. for (var i=oldlen; i<newlen; i++) a[i]={}; // e.g. set
  650. } else {
  651. for (var i=oldlen; i<newlen; i++) a[i]=defaultvalue;
  652. }
  653. } else {
  654. for (var i=oldlen; i<newlen; i++) a[i]=[]; // nested array
  655. }
  656. }
  657. if (argNo < p.length-1){
  658. // multi argNo
  659. for (var i=0; i<newlen; i++) a[i]=setLength(a[i],argNo+1);
  660. }
  661. return a;
  662. }
  663. return setLength(arr,2);
  664. },
  665. arrayEq: function(a,b){
  666. if (a===null) return b===null;
  667. if (b===null) return false;
  668. if (a.length!==b.length) return false;
  669. for (var i=0; i<a.length; i++) if (a[i]!==b[i]) return false;
  670. return true;
  671. },
  672. arrayClone: function(type,src,srcpos,end,dst,dstpos){
  673. // type: 0 for references, "refset" for calling refSet(), a function for new type()
  674. // src must not be null
  675. // This function does not range check.
  676. if (rtl.isFunction(type)){
  677. for (; srcpos<end; srcpos++) dst[dstpos++] = new type(src[srcpos]); // clone record
  678. } else if((typeof(type)==="string") && (type === 'refSet')) {
  679. for (; srcpos<end; srcpos++) dst[dstpos++] = rtl.refSet(src[srcpos]); // ref set
  680. } else {
  681. for (; srcpos<end; srcpos++) dst[dstpos++] = src[srcpos]; // reference
  682. };
  683. },
  684. arrayConcat: function(type){
  685. // type: see rtl.arrayClone
  686. var a = [];
  687. var l = 0;
  688. for (var i=1; i<arguments.length; i++) l+=arguments[i].length;
  689. a.length = l;
  690. l=0;
  691. for (var i=1; i<arguments.length; i++){
  692. var src = arguments[i];
  693. if (src == null) continue;
  694. rtl.arrayClone(type,src,0,src.length,a,l);
  695. l+=src.length;
  696. };
  697. return a;
  698. },
  699. arrayCopy: function(type, srcarray, index, count){
  700. // type: see rtl.arrayClone
  701. // if count is missing, use srcarray.length
  702. if (srcarray == null) return [];
  703. if (index < 0) index = 0;
  704. if (count === undefined) count=srcarray.length;
  705. var end = index+count;
  706. if (end>srcarray.length) end = srcarray.length;
  707. if (index>=end) return [];
  708. if (type===0){
  709. return srcarray.slice(index,end);
  710. } else {
  711. var a = [];
  712. a.length = end-index;
  713. rtl.arrayClone(type,srcarray,index,end,a,0);
  714. return a;
  715. }
  716. },
  717. setCharAt: function(s,index,c){
  718. return s.substr(0,index)+c+s.substr(index+1);
  719. },
  720. getResStr: function(mod,name){
  721. var rs = mod.$resourcestrings[name];
  722. return rs.current?rs.current:rs.org;
  723. },
  724. createSet: function(){
  725. var s = {};
  726. for (var i=0; i<arguments.length; i++){
  727. if (arguments[i]!=null){
  728. s[arguments[i]]=true;
  729. } else {
  730. var first=arguments[i+=1];
  731. var last=arguments[i+=1];
  732. for(var j=first; j<=last; j++) s[j]=true;
  733. }
  734. }
  735. return s;
  736. },
  737. cloneSet: function(s){
  738. var r = {};
  739. for (var key in s) r[key]=true;
  740. return r;
  741. },
  742. refSet: function(s){
  743. s.$shared = true;
  744. return s;
  745. },
  746. includeSet: function(s,enumvalue){
  747. if (s.$shared) s = rtl.cloneSet(s);
  748. s[enumvalue] = true;
  749. return s;
  750. },
  751. excludeSet: function(s,enumvalue){
  752. if (s.$shared) s = rtl.cloneSet(s);
  753. delete s[enumvalue];
  754. return s;
  755. },
  756. diffSet: function(s,t){
  757. var r = {};
  758. for (var key in s) if (!t[key]) r[key]=true;
  759. delete r.$shared;
  760. return r;
  761. },
  762. unionSet: function(s,t){
  763. var r = {};
  764. for (var key in s) r[key]=true;
  765. for (var key in t) r[key]=true;
  766. delete r.$shared;
  767. return r;
  768. },
  769. intersectSet: function(s,t){
  770. var r = {};
  771. for (var key in s) if (t[key]) r[key]=true;
  772. delete r.$shared;
  773. return r;
  774. },
  775. symDiffSet: function(s,t){
  776. var r = {};
  777. for (var key in s) if (!t[key]) r[key]=true;
  778. for (var key in t) if (!s[key]) r[key]=true;
  779. delete r.$shared;
  780. return r;
  781. },
  782. eqSet: function(s,t){
  783. for (var key in s) if (!t[key] && (key!='$shared')) return false;
  784. for (var key in t) if (!s[key] && (key!='$shared')) return false;
  785. return true;
  786. },
  787. neSet: function(s,t){
  788. return !rtl.eqSet(s,t);
  789. },
  790. leSet: function(s,t){
  791. for (var key in s) if (!t[key] && (key!='$shared')) return false;
  792. return true;
  793. },
  794. geSet: function(s,t){
  795. for (var key in t) if (!s[key] && (key!='$shared')) return false;
  796. return true;
  797. },
  798. strSetLength: function(s,newlen){
  799. var oldlen = s.length;
  800. if (oldlen > newlen){
  801. return s.substring(0,newlen);
  802. } else if (s.repeat){
  803. // Note: repeat needs ECMAScript6!
  804. return s+' '.repeat(newlen-oldlen);
  805. } else {
  806. while (oldlen<newlen){
  807. s+=' ';
  808. oldlen++;
  809. };
  810. return s;
  811. }
  812. },
  813. spaceLeft: function(s,width){
  814. var l=s.length;
  815. if (l>=width) return s;
  816. if (s.repeat){
  817. // Note: repeat needs ECMAScript6!
  818. return ' '.repeat(width-l) + s;
  819. } else {
  820. while (l<width){
  821. s=' '+s;
  822. l++;
  823. };
  824. };
  825. },
  826. floatToStr : function(d,w,p){
  827. // input 1-3 arguments: double, width, precision
  828. if (arguments.length>2){
  829. return rtl.spaceLeft(d.toFixed(p),w);
  830. } else {
  831. // exponent width
  832. var pad = "";
  833. var ad = Math.abs(d);
  834. if (ad<1.0e+10) {
  835. pad='00';
  836. } else if (ad<1.0e+100) {
  837. pad='0';
  838. }
  839. if (arguments.length<2) {
  840. w=9;
  841. } else if (w<9) {
  842. w=9;
  843. }
  844. var p = w-8;
  845. var s=(d>0 ? " " : "" ) + d.toExponential(p);
  846. s=s.replace(/e(.)/,'E$1'+pad);
  847. return rtl.spaceLeft(s,w);
  848. }
  849. },
  850. initRTTI: function(){
  851. if (rtl.debug_rtti) rtl.debug('initRTTI');
  852. // base types
  853. rtl.tTypeInfo = { name: "tTypeInfo" };
  854. function newBaseTI(name,kind,ancestor){
  855. if (!ancestor) ancestor = rtl.tTypeInfo;
  856. if (rtl.debug_rtti) rtl.debug('initRTTI.newBaseTI "'+name+'" '+kind+' ("'+ancestor.name+'")');
  857. var t = Object.create(ancestor);
  858. t.name = name;
  859. t.kind = kind;
  860. rtl[name] = t;
  861. return t;
  862. };
  863. function newBaseInt(name,minvalue,maxvalue,ordtype){
  864. var t = newBaseTI(name,1 /* tkInteger */,rtl.tTypeInfoInteger);
  865. t.minvalue = minvalue;
  866. t.maxvalue = maxvalue;
  867. t.ordtype = ordtype;
  868. return t;
  869. };
  870. newBaseTI("tTypeInfoInteger",1 /* tkInteger */);
  871. newBaseInt("shortint",-0x80,0x7f,0);
  872. newBaseInt("byte",0,0xff,1);
  873. newBaseInt("smallint",-0x8000,0x7fff,2);
  874. newBaseInt("word",0,0xffff,3);
  875. newBaseInt("longint",-0x80000000,0x7fffffff,4);
  876. newBaseInt("longword",0,0xffffffff,5);
  877. newBaseInt("nativeint",-0x10000000000000,0xfffffffffffff,6);
  878. newBaseInt("nativeuint",0,0xfffffffffffff,7);
  879. newBaseTI("char",2 /* tkChar */);
  880. newBaseTI("string",3 /* tkString */);
  881. newBaseTI("tTypeInfoEnum",4 /* tkEnumeration */,rtl.tTypeInfoInteger);
  882. newBaseTI("tTypeInfoSet",5 /* tkSet */);
  883. newBaseTI("double",6 /* tkDouble */);
  884. newBaseTI("boolean",7 /* tkBool */);
  885. newBaseTI("tTypeInfoProcVar",8 /* tkProcVar */);
  886. newBaseTI("tTypeInfoMethodVar",9 /* tkMethod */,rtl.tTypeInfoProcVar);
  887. newBaseTI("tTypeInfoArray",10 /* tkArray */);
  888. newBaseTI("tTypeInfoDynArray",11 /* tkDynArray */);
  889. newBaseTI("tTypeInfoPointer",15 /* tkPointer */);
  890. var t = newBaseTI("pointer",15 /* tkPointer */,rtl.tTypeInfoPointer);
  891. t.reftype = null;
  892. newBaseTI("jsvalue",16 /* tkJSValue */);
  893. newBaseTI("tTypeInfoRefToProcVar",17 /* tkRefToProcVar */,rtl.tTypeInfoProcVar);
  894. // member kinds
  895. rtl.tTypeMember = {};
  896. function newMember(name,kind){
  897. var m = Object.create(rtl.tTypeMember);
  898. m.name = name;
  899. m.kind = kind;
  900. rtl[name] = m;
  901. };
  902. newMember("tTypeMemberField",1); // tmkField
  903. newMember("tTypeMemberMethod",2); // tmkMethod
  904. newMember("tTypeMemberProperty",3); // tmkProperty
  905. // base object for storing members: a simple object
  906. rtl.tTypeMembers = {};
  907. // tTypeInfoStruct - base object for tTypeInfoClass, tTypeInfoRecord, tTypeInfoInterface
  908. var tis = newBaseTI("tTypeInfoStruct",0);
  909. tis.$addMember = function(name,ancestor,options){
  910. if (rtl.debug_rtti){
  911. if (!rtl.hasString(name) || (name.charAt()==='$')) throw 'invalid member "'+name+'", this="'+this.name+'"';
  912. if (!rtl.is(ancestor,rtl.tTypeMember)) throw 'invalid ancestor "'+ancestor+':'+ancestor.name+'", "'+this.name+'.'+name+'"';
  913. if ((options!=undefined) && (typeof(options)!='object')) throw 'invalid options "'+options+'", "'+this.name+'.'+name+'"';
  914. };
  915. var t = Object.create(ancestor);
  916. t.name = name;
  917. this.members[name] = t;
  918. this.names.push(name);
  919. if (rtl.isObject(options)){
  920. for (var key in options) if (options.hasOwnProperty(key)) t[key] = options[key];
  921. };
  922. return t;
  923. };
  924. tis.addField = function(name,type,options){
  925. var t = this.$addMember(name,rtl.tTypeMemberField,options);
  926. if (rtl.debug_rtti){
  927. if (!rtl.is(type,rtl.tTypeInfo)) throw 'invalid type "'+type+'", "'+this.name+'.'+name+'"';
  928. };
  929. t.typeinfo = type;
  930. this.fields.push(name);
  931. return t;
  932. };
  933. tis.addFields = function(){
  934. var i=0;
  935. while(i<arguments.length){
  936. var name = arguments[i++];
  937. var type = arguments[i++];
  938. if ((i<arguments.length) && (typeof(arguments[i])==='object')){
  939. this.addField(name,type,arguments[i++]);
  940. } else {
  941. this.addField(name,type);
  942. };
  943. };
  944. };
  945. tis.addMethod = function(name,methodkind,params,result,options){
  946. var t = this.$addMember(name,rtl.tTypeMemberMethod,options);
  947. t.methodkind = methodkind;
  948. t.procsig = rtl.newTIProcSig(params);
  949. t.procsig.resulttype = result?result:null;
  950. this.methods.push(name);
  951. return t;
  952. };
  953. tis.addProperty = function(name,flags,result,getter,setter,options){
  954. var t = this.$addMember(name,rtl.tTypeMemberProperty,options);
  955. t.flags = flags;
  956. t.typeinfo = result;
  957. t.getter = getter;
  958. t.setter = setter;
  959. // Note: in options: params, stored, defaultvalue
  960. if (rtl.isArray(t.params)) t.params = rtl.newTIParams(t.params);
  961. this.properties.push(name);
  962. if (!rtl.isString(t.stored)) t.stored = "";
  963. return t;
  964. };
  965. tis.getField = function(index){
  966. return this.members[this.fields[index]];
  967. };
  968. tis.getMethod = function(index){
  969. return this.members[this.methods[index]];
  970. };
  971. tis.getProperty = function(index){
  972. return this.members[this.properties[index]];
  973. };
  974. newBaseTI("tTypeInfoRecord",12 /* tkRecord */,rtl.tTypeInfoStruct);
  975. newBaseTI("tTypeInfoClass",13 /* tkClass */,rtl.tTypeInfoStruct);
  976. newBaseTI("tTypeInfoClassRef",14 /* tkClassRef */);
  977. newBaseTI("tTypeInfoInterface",15 /* tkInterface */,rtl.tTypeInfoStruct);
  978. },
  979. tSectionRTTI: {
  980. $module: null,
  981. $inherited: function(name,ancestor,o){
  982. if (rtl.debug_rtti){
  983. rtl.debug('tSectionRTTI.newTI "'+(this.$module?this.$module.$name:"(no module)")
  984. +'"."'+name+'" ('+ancestor.name+') '+(o?'init':'forward'));
  985. };
  986. var t = this[name];
  987. if (t){
  988. if (!t.$forward) throw 'duplicate type "'+name+'"';
  989. if (!ancestor.isPrototypeOf(t)) throw 'typeinfo ancestor mismatch "'+name+'" ancestor="'+ancestor.name+'" t.name="'+t.name+'"';
  990. } else {
  991. t = Object.create(ancestor);
  992. t.name = name;
  993. t.$module = this.$module;
  994. this[name] = t;
  995. }
  996. if (o){
  997. delete t.$forward;
  998. for (var key in o) if (o.hasOwnProperty(key)) t[key]=o[key];
  999. } else {
  1000. t.$forward = true;
  1001. }
  1002. return t;
  1003. },
  1004. $Scope: function(name,ancestor,o){
  1005. var t=this.$inherited(name,ancestor,o);
  1006. t.members = {};
  1007. t.names = [];
  1008. t.fields = [];
  1009. t.methods = [];
  1010. t.properties = [];
  1011. return t;
  1012. },
  1013. $TI: function(name,kind,o){ var t=this.$inherited(name,rtl.tTypeInfo,o); t.kind = kind; return t; },
  1014. $Int: function(name,o){ return this.$inherited(name,rtl.tTypeInfoInteger,o); },
  1015. $Enum: function(name,o){ return this.$inherited(name,rtl.tTypeInfoEnum,o); },
  1016. $Set: function(name,o){ return this.$inherited(name,rtl.tTypeInfoSet,o); },
  1017. $StaticArray: function(name,o){ return this.$inherited(name,rtl.tTypeInfoArray,o); },
  1018. $DynArray: function(name,o){ return this.$inherited(name,rtl.tTypeInfoDynArray,o); },
  1019. $ProcVar: function(name,o){ return this.$inherited(name,rtl.tTypeInfoProcVar,o); },
  1020. $RefToProcVar: function(name,o){ return this.$inherited(name,rtl.tTypeInfoRefToProcVar,o); },
  1021. $MethodVar: function(name,o){ return this.$inherited(name,rtl.tTypeInfoMethodVar,o); },
  1022. $Record: function(name,o){ return this.$Scope(name,rtl.tTypeInfoRecord,o); },
  1023. $Class: function(name,o){ return this.$Scope(name,rtl.tTypeInfoClass,o); },
  1024. $ClassRef: function(name,o){ return this.$inherited(name,rtl.tTypeInfoClassRef,o); },
  1025. $Pointer: function(name,o){ return this.$inherited(name,rtl.tTypeInfoPointer,o); },
  1026. $Interface: function(name,o){ return this.$Scope(name,rtl.tTypeInfoInterface,o); }
  1027. },
  1028. newTIParam: function(param){
  1029. // param is an array, 0=name, 1=type, 2=optional flags
  1030. var t = {
  1031. name: param[0],
  1032. typeinfo: param[1],
  1033. flags: (rtl.isNumber(param[2]) ? param[2] : 0)
  1034. };
  1035. return t;
  1036. },
  1037. newTIParams: function(list){
  1038. // list: optional array of [paramname,typeinfo,optional flags]
  1039. var params = [];
  1040. if (rtl.isArray(list)){
  1041. for (var i=0; i<list.length; i++) params.push(rtl.newTIParam(list[i]));
  1042. };
  1043. return params;
  1044. },
  1045. newTIProcSig: function(params,result,flags){
  1046. var s = {
  1047. params: rtl.newTIParams(params),
  1048. resulttype: result,
  1049. flags: flags
  1050. };
  1051. return s;
  1052. }
  1053. }
  1054. rtl.module("System",[],function () {
  1055. "use strict";
  1056. var $mod = this;
  1057. var $impl = $mod.$impl;
  1058. this.LineEnding = "\n";
  1059. this.sLineBreak = $mod.LineEnding;
  1060. rtl.createClass($mod,"TObject",null,function () {
  1061. this.$init = function () {
  1062. };
  1063. this.$final = function () {
  1064. };
  1065. this.Create = function () {
  1066. };
  1067. this.AfterConstruction = function () {
  1068. };
  1069. this.BeforeDestruction = function () {
  1070. };
  1071. });
  1072. this.Trunc = function (A) {
  1073. if (!Math.trunc) {
  1074. Math.trunc = function(v) {
  1075. v = +v;
  1076. if (!isFinite(v)) return v;
  1077. return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
  1078. };
  1079. }
  1080. $mod.Trunc = Math.trunc;
  1081. return Math.trunc(A);
  1082. };
  1083. this.Int = function (A) {
  1084. var Result = 0.0;
  1085. Result = Math.trunc(A);
  1086. return Result;
  1087. };
  1088. this.Copy = function (S, Index, Size) {
  1089. if (Index<1) Index = 1;
  1090. return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
  1091. };
  1092. this.Copy$1 = function (S, Index) {
  1093. if (Index<1) Index = 1;
  1094. return S.substr(Index-1);
  1095. };
  1096. this.Delete = function (S, Index, Size) {
  1097. var h = "";
  1098. if (((Index < 1) || (Index > S.get().length)) || (Size <= 0)) return;
  1099. h = S.get();
  1100. S.set($mod.Copy(h,1,Index - 1) + $mod.Copy$1(h,Index + Size));
  1101. };
  1102. this.Pos = function (Search, InString) {
  1103. return InString.indexOf(Search)+1;
  1104. };
  1105. this.Insert = function (Insertion, Target, Index) {
  1106. var t = "";
  1107. if (Insertion === "") return;
  1108. t = Target.get();
  1109. if (Index < 1) {
  1110. Target.set(Insertion + t)}
  1111. else if (Index > t.length) {
  1112. Target.set(t + Insertion)}
  1113. else Target.set(($mod.Copy(t,1,Index - 1) + Insertion) + $mod.Copy(t,Index,t.length));
  1114. };
  1115. this.upcase = function (c) {
  1116. return c.toUpperCase();
  1117. };
  1118. this.val = function (S, NI, Code) {
  1119. var x = 0.0;
  1120. Code.set(0);
  1121. x = Number(S);
  1122. if (isNaN(x) || (x !== $mod.Int(x))) {
  1123. Code.set(1)}
  1124. else NI.set($mod.Trunc(x));
  1125. };
  1126. this.StringOfChar = function (c, l) {
  1127. var Result = "";
  1128. var i = 0;
  1129. Result = "";
  1130. for (var $l1 = 1, $end2 = l; $l1 <= $end2; $l1++) {
  1131. i = $l1;
  1132. Result = Result + c;
  1133. };
  1134. return Result;
  1135. };
  1136. this.Writeln = function () {
  1137. var i = 0;
  1138. var l = 0;
  1139. var s = "";
  1140. l = rtl.length(arguments) - 1;
  1141. if ($impl.WriteCallBack != null) {
  1142. for (var $l1 = 0, $end2 = l; $l1 <= $end2; $l1++) {
  1143. i = $l1;
  1144. $impl.WriteCallBack(arguments[i],i === l);
  1145. };
  1146. } else {
  1147. s = $impl.WriteBuf;
  1148. for (var $l3 = 0, $end4 = l; $l3 <= $end4; $l3++) {
  1149. i = $l3;
  1150. s = s + ("" + arguments[i]);
  1151. };
  1152. console.log(s);
  1153. $impl.WriteBuf = "";
  1154. };
  1155. };
  1156. this.SetWriteCallBack = function (H) {
  1157. var Result = null;
  1158. Result = $impl.WriteCallBack;
  1159. $impl.WriteCallBack = H;
  1160. return Result;
  1161. };
  1162. $mod.$init = function () {
  1163. rtl.exitcode = 0;
  1164. };
  1165. },null,function () {
  1166. "use strict";
  1167. var $mod = this;
  1168. var $impl = $mod.$impl;
  1169. $impl.WriteBuf = "";
  1170. $impl.WriteCallBack = null;
  1171. });
  1172. rtl.module("Types",["System"],function () {
  1173. "use strict";
  1174. var $mod = this;
  1175. });
  1176. rtl.module("JS",["System","Types"],function () {
  1177. "use strict";
  1178. var $mod = this;
  1179. this.isInteger = function (v) {
  1180. return Math.floor(v)===v;
  1181. };
  1182. this.isNull = function (v) {
  1183. return v === null;
  1184. };
  1185. this.TJSValueType = {"0": "jvtNull", jvtNull: 0, "1": "jvtBoolean", jvtBoolean: 1, "2": "jvtInteger", jvtInteger: 2, "3": "jvtFloat", jvtFloat: 3, "4": "jvtString", jvtString: 4, "5": "jvtObject", jvtObject: 5, "6": "jvtArray", jvtArray: 6};
  1186. this.GetValueType = function (JS) {
  1187. var Result = 0;
  1188. var t = "";
  1189. if ($mod.isNull(JS)) {
  1190. Result = $mod.TJSValueType.jvtNull}
  1191. else {
  1192. t = typeof(JS);
  1193. if (t === "string") {
  1194. Result = $mod.TJSValueType.jvtString}
  1195. else if (t === "boolean") {
  1196. Result = $mod.TJSValueType.jvtBoolean}
  1197. else if (t === "object") {
  1198. if (rtl.isArray(JS)) {
  1199. Result = $mod.TJSValueType.jvtArray}
  1200. else Result = $mod.TJSValueType.jvtObject;
  1201. } else if (t === "number") if ($mod.isInteger(JS)) {
  1202. Result = $mod.TJSValueType.jvtInteger}
  1203. else Result = $mod.TJSValueType.jvtFloat;
  1204. };
  1205. return Result;
  1206. };
  1207. });
  1208. rtl.module("Web",["System","Types","JS"],function () {
  1209. "use strict";
  1210. var $mod = this;
  1211. });
  1212. rtl.module("browserconsole",["System","JS","Web"],function () {
  1213. "use strict";
  1214. var $mod = this;
  1215. var $impl = $mod.$impl;
  1216. this.DefaultMaxConsoleLines = 25;
  1217. 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) + "}";
  1218. this.ConsoleElementID = "";
  1219. this.ConsoleStyle = "";
  1220. this.MaxConsoleLines = 0;
  1221. this.ConsoleLinesToBrowserLog = false;
  1222. this.ResetConsole = function () {
  1223. if ($impl.LinesParent === null) return;
  1224. while ($impl.LinesParent.firstElementChild !== null) $impl.LinesParent.removeChild($impl.LinesParent.firstElementChild);
  1225. $impl.AppendLine();
  1226. };
  1227. this.InitConsole = function () {
  1228. if ($impl.ConsoleElement === null) return;
  1229. if ($impl.ConsoleElement.nodeName.toLowerCase() !== "body") {
  1230. while ($impl.ConsoleElement.firstElementChild !== null) $impl.ConsoleElement.removeChild($impl.ConsoleElement.firstElementChild);
  1231. };
  1232. $impl.StyleElement = document.createElement("style");
  1233. $impl.StyleElement.innerText = $mod.ConsoleStyle;
  1234. $impl.ConsoleElement.appendChild($impl.StyleElement);
  1235. $impl.LinesParent = document.createElement("div");
  1236. $impl.ConsoleElement.appendChild($impl.LinesParent);
  1237. };
  1238. this.HookConsole = function () {
  1239. $impl.ConsoleElement = null;
  1240. if ($mod.ConsoleElementID !== "") $impl.ConsoleElement = document.getElementById($mod.ConsoleElementID);
  1241. if ($impl.ConsoleElement === null) $impl.ConsoleElement = document.body;
  1242. if ($impl.ConsoleElement === null) return;
  1243. $mod.InitConsole();
  1244. $mod.ResetConsole();
  1245. pas.System.SetWriteCallBack($impl.WriteConsole);
  1246. };
  1247. $mod.$init = function () {
  1248. $mod.ConsoleLinesToBrowserLog = true;
  1249. $mod.ConsoleElementID = "pasjsconsole";
  1250. $mod.ConsoleStyle = $mod.DefaultConsoleStyle;
  1251. $mod.MaxConsoleLines = 25;
  1252. $mod.HookConsole();
  1253. };
  1254. },null,function () {
  1255. "use strict";
  1256. var $mod = this;
  1257. var $impl = $mod.$impl;
  1258. $impl.LastLine = null;
  1259. $impl.StyleElement = null;
  1260. $impl.LinesParent = null;
  1261. $impl.ConsoleElement = null;
  1262. $impl.AppendLine = function () {
  1263. var CurrentCount = 0;
  1264. var S = null;
  1265. CurrentCount = 0;
  1266. S = $impl.LinesParent.firstChild;
  1267. while (S != null) {
  1268. CurrentCount += 1;
  1269. S = S.nextSibling;
  1270. };
  1271. while (CurrentCount > $mod.MaxConsoleLines) {
  1272. CurrentCount -= 1;
  1273. $impl.LinesParent.removeChild($impl.LinesParent.firstChild);
  1274. };
  1275. $impl.LastLine = document.createElement("div");
  1276. $impl.LastLine.className = "pasconsole";
  1277. $impl.LinesParent.appendChild($impl.LastLine);
  1278. };
  1279. $impl.WriteConsole = function (S, NewLine) {
  1280. var CL = "";
  1281. CL = $impl.LastLine.innerText;
  1282. CL = CL + ("" + S);
  1283. $impl.LastLine.innerText = CL;
  1284. if (NewLine) {
  1285. if ($mod.ConsoleLinesToBrowserLog) window.console.log(CL);
  1286. $impl.AppendLine();
  1287. };
  1288. };
  1289. });
  1290. rtl.module("RTLConsts",["System"],function () {
  1291. "use strict";
  1292. var $mod = this;
  1293. this.SArgumentMissing = 'Missing argument in format "%s"';
  1294. this.SInvalidFormat = 'Invalid format specifier : "%s"';
  1295. this.SInvalidArgIndex = 'Invalid argument index in format: "%s"';
  1296. this.SErrInvalidInteger = 'Invalid integer value: "%s"';
  1297. this.SErrInvalidFloat = 'Invalid floating-point value: "%s"';
  1298. });
  1299. rtl.module("SysUtils",["System","RTLConsts","JS"],function () {
  1300. "use strict";
  1301. var $mod = this;
  1302. var $impl = $mod.$impl;
  1303. rtl.createClass($mod,"Exception",pas.System.TObject,function () {
  1304. this.$init = function () {
  1305. pas.System.TObject.$init.call(this);
  1306. this.fMessage = "";
  1307. };
  1308. this.CreateFmt = function (Msg, Args) {
  1309. this.fMessage = $mod.Format(Msg,Args);
  1310. };
  1311. });
  1312. rtl.createClass($mod,"EConvertError",$mod.Exception,function () {
  1313. });
  1314. this.TrimLeft = function (S) {
  1315. return S.replace(/^[\s\uFEFF\xA0\x00-\x1f]+/,'');
  1316. };
  1317. this.Format = function (Fmt, Args) {
  1318. var Result = "";
  1319. var ChPos = 0;
  1320. var OldPos = 0;
  1321. var ArgPos = 0;
  1322. var DoArg = 0;
  1323. var Len = 0;
  1324. var Hs = "";
  1325. var ToAdd = "";
  1326. var Index = 0;
  1327. var Width = 0;
  1328. var Prec = 0;
  1329. var Left = false;
  1330. var Fchar = "";
  1331. var vq = 0;
  1332. function ReadFormat() {
  1333. var Result = "";
  1334. var Value = 0;
  1335. function ReadInteger() {
  1336. var Code = 0;
  1337. var ArgN = 0;
  1338. if (Value !== -1) return;
  1339. OldPos = ChPos;
  1340. while (((ChPos <= Len) && (Fmt.charAt(ChPos - 1) <= "9")) && (Fmt.charAt(ChPos - 1) >= "0")) ChPos += 1;
  1341. if (ChPos > Len) $impl.DoFormatError(1,Fmt);
  1342. if (Fmt.charAt(ChPos - 1) === "*") {
  1343. if (Index === -1) {
  1344. ArgN = ArgPos}
  1345. else {
  1346. ArgN = Index;
  1347. Index += 1;
  1348. };
  1349. if ((ChPos > OldPos) || (ArgN > (rtl.length(Args) - 1))) $impl.DoFormatError(1,Fmt);
  1350. ArgPos = ArgN + 1;
  1351. if (rtl.isNumber(Args[ArgN]) && pas.JS.isInteger(Args[ArgN])) {
  1352. Value = Math.floor(Args[ArgN])}
  1353. else $impl.DoFormatError(1,Fmt);
  1354. ChPos += 1;
  1355. } else {
  1356. if (OldPos < ChPos) {
  1357. pas.System.val(pas.System.Copy(Fmt,OldPos,ChPos - OldPos),{get: function () {
  1358. return Value;
  1359. }, set: function (v) {
  1360. Value = v;
  1361. }},{get: function () {
  1362. return Code;
  1363. }, set: function (v) {
  1364. Code = v;
  1365. }});
  1366. if (Code > 0) $impl.DoFormatError(1,Fmt);
  1367. } else Value = -1;
  1368. };
  1369. };
  1370. function ReadIndex() {
  1371. if (Fmt.charAt(ChPos - 1) !== ":") {
  1372. ReadInteger()}
  1373. else Value = 0;
  1374. if (Fmt.charAt(ChPos - 1) === ":") {
  1375. if (Value === -1) $impl.DoFormatError(2,Fmt);
  1376. Index = Value;
  1377. Value = -1;
  1378. ChPos += 1;
  1379. };
  1380. };
  1381. function ReadLeft() {
  1382. if (Fmt.charAt(ChPos - 1) === "-") {
  1383. Left = true;
  1384. ChPos += 1;
  1385. } else Left = false;
  1386. };
  1387. function ReadWidth() {
  1388. ReadInteger();
  1389. if (Value !== -1) {
  1390. Width = Value;
  1391. Value = -1;
  1392. };
  1393. };
  1394. function ReadPrec() {
  1395. if (Fmt.charAt(ChPos - 1) === ".") {
  1396. ChPos += 1;
  1397. ReadInteger();
  1398. if (Value === -1) Value = 0;
  1399. Prec = Value;
  1400. };
  1401. };
  1402. Index = -1;
  1403. Width = -1;
  1404. Prec = -1;
  1405. Value = -1;
  1406. ChPos += 1;
  1407. if (Fmt.charAt(ChPos - 1) === "%") {
  1408. Result = "%";
  1409. return Result;
  1410. };
  1411. ReadIndex();
  1412. ReadLeft();
  1413. ReadWidth();
  1414. ReadPrec();
  1415. Result = pas.System.upcase(Fmt.charAt(ChPos - 1));
  1416. return Result;
  1417. };
  1418. function Checkarg(AT, err) {
  1419. var Result = false;
  1420. Result = false;
  1421. if (Index === -1) {
  1422. DoArg = ArgPos}
  1423. else DoArg = Index;
  1424. ArgPos = DoArg + 1;
  1425. if ((DoArg > (rtl.length(Args) - 1)) || (pas.JS.GetValueType(Args[DoArg]) !== AT)) {
  1426. if (err) $impl.DoFormatError(3,Fmt);
  1427. ArgPos -= 1;
  1428. return Result;
  1429. };
  1430. Result = true;
  1431. return Result;
  1432. };
  1433. Result = "";
  1434. Len = Fmt.length;
  1435. ChPos = 1;
  1436. OldPos = 1;
  1437. ArgPos = 0;
  1438. while (ChPos <= Len) {
  1439. while ((ChPos <= Len) && (Fmt.charAt(ChPos - 1) !== "%")) ChPos += 1;
  1440. if (ChPos > OldPos) Result = Result + pas.System.Copy(Fmt,OldPos,ChPos - OldPos);
  1441. if (ChPos < Len) {
  1442. Fchar = ReadFormat();
  1443. var $tmp1 = Fchar;
  1444. if ($tmp1 === "D") {
  1445. Checkarg(pas.JS.TJSValueType.jvtInteger,true);
  1446. ToAdd = $mod.IntToStr(Math.floor(Args[DoArg]));
  1447. Width = Math.abs(Width);
  1448. Index = Prec - ToAdd.length;
  1449. if (ToAdd.charAt(0) !== "-") {
  1450. ToAdd = pas.System.StringOfChar("0",Index) + ToAdd}
  1451. else pas.System.Insert(pas.System.StringOfChar("0",Index + 1),{get: function () {
  1452. return ToAdd;
  1453. }, set: function (v) {
  1454. ToAdd = v;
  1455. }},2);
  1456. } else if ($tmp1 === "U") {
  1457. Checkarg(pas.JS.TJSValueType.jvtInteger,true);
  1458. if (Math.floor(Args[DoArg]) < 0) $impl.DoFormatError(3,Fmt);
  1459. ToAdd = $mod.IntToStr(Math.floor(Args[DoArg]));
  1460. Width = Math.abs(Width);
  1461. Index = Prec - ToAdd.length;
  1462. ToAdd = pas.System.StringOfChar("0",Index) + ToAdd;
  1463. } else if ($tmp1 === "E") {
  1464. if (Checkarg(pas.JS.TJSValueType.jvtFloat,false) || Checkarg(pas.JS.TJSValueType.jvtInteger,true)) ToAdd = $mod.FloatToStrF(rtl.getNumber(Args[DoArg]),$mod.TFloatFormat.ffFixed,9999,Prec);
  1465. } else if ($tmp1 === "F") {
  1466. if (Checkarg(pas.JS.TJSValueType.jvtFloat,false) || Checkarg(pas.JS.TJSValueType.jvtInteger,true)) ToAdd = $mod.FloatToStrF(rtl.getNumber(Args[DoArg]),$mod.TFloatFormat.ffFixed,9999,Prec);
  1467. } else if ($tmp1 === "G") {
  1468. if (Checkarg(pas.JS.TJSValueType.jvtFloat,false) || Checkarg(pas.JS.TJSValueType.jvtInteger,true)) ToAdd = $mod.FloatToStrF(rtl.getNumber(Args[DoArg]),$mod.TFloatFormat.ffGeneral,Prec,3);
  1469. } else if ($tmp1 === "N") {
  1470. if (Checkarg(pas.JS.TJSValueType.jvtFloat,false) || Checkarg(pas.JS.TJSValueType.jvtInteger,true)) ToAdd = $mod.FloatToStrF(rtl.getNumber(Args[DoArg]),$mod.TFloatFormat.ffNumber,9999,Prec);
  1471. } else if ($tmp1 === "M") {
  1472. if (Checkarg(pas.JS.TJSValueType.jvtFloat,false) || Checkarg(pas.JS.TJSValueType.jvtInteger,true)) ToAdd = $mod.FloatToStrF(rtl.getNumber(Args[DoArg]),$mod.TFloatFormat.ffCurrency,9999,Prec);
  1473. } else if ($tmp1 === "S") {
  1474. Checkarg(pas.JS.TJSValueType.jvtString,true);
  1475. Hs = "" + Args[DoArg];
  1476. Index = Hs.length;
  1477. if ((Prec !== -1) && (Index > Prec)) Index = Prec;
  1478. ToAdd = pas.System.Copy(Hs,1,Index);
  1479. } else if ($tmp1 === "P") {
  1480. Checkarg(pas.JS.TJSValueType.jvtInteger,true);
  1481. ToAdd = $mod.IntToHex(Math.floor(Args[DoArg]),31);
  1482. } else if ($tmp1 === "X") {
  1483. Checkarg(pas.JS.TJSValueType.jvtInteger,true);
  1484. vq = Math.floor(Args[DoArg]);
  1485. Index = 31;
  1486. if (Prec > Index) {
  1487. ToAdd = $mod.IntToHex(vq,Index)}
  1488. else {
  1489. Index = 1;
  1490. while (((1 << (Index * 4)) <= vq) && (Index < 16)) Index += 1;
  1491. if (Index > Prec) Prec = Index;
  1492. ToAdd = $mod.IntToHex(vq,Prec);
  1493. };
  1494. } else if ($tmp1 === "%") ToAdd = "%";
  1495. if (Width !== -1) if (ToAdd.length < Width) if (!Left) {
  1496. ToAdd = pas.System.StringOfChar(" ",Width - ToAdd.length) + ToAdd}
  1497. else ToAdd = ToAdd + pas.System.StringOfChar(" ",Width - ToAdd.length);
  1498. Result = Result + ToAdd;
  1499. };
  1500. ChPos += 1;
  1501. OldPos = ChPos;
  1502. };
  1503. return Result;
  1504. };
  1505. this.TStringReplaceFlag = {"0": "rfReplaceAll", rfReplaceAll: 0, "1": "rfIgnoreCase", rfIgnoreCase: 1};
  1506. this.StringReplace = function (aOriginal, aSearch, aReplace, Flags) {
  1507. var Result = "";
  1508. var REFlags = "";
  1509. var REString = "";
  1510. REFlags = "";
  1511. if ($mod.TStringReplaceFlag.rfReplaceAll in Flags) REFlags = "g";
  1512. if ($mod.TStringReplaceFlag.rfIgnoreCase in Flags) REFlags = REFlags + "i";
  1513. REString = aSearch.replace(new RegExp($impl.RESpecials,"g"),"\\$1");
  1514. Result = aOriginal.replace(new RegExp(REString,REFlags),aReplace);
  1515. return Result;
  1516. };
  1517. this.IntToStr = function (Value) {
  1518. var Result = "";
  1519. Result = "" + Value;
  1520. return Result;
  1521. };
  1522. this.TryStrToInt$1 = function (S, res) {
  1523. var Result = false;
  1524. var Radix = 10;
  1525. var F = "";
  1526. var N = "";
  1527. var J = undefined;
  1528. N = S;
  1529. F = pas.System.Copy(N,1,1);
  1530. if (F === "$") {
  1531. Radix = 16}
  1532. else if (F === "&") {
  1533. Radix = 8}
  1534. else if (F === "%") Radix = 2;
  1535. if (Radix !== 10) pas.System.Delete({get: function () {
  1536. return N;
  1537. }, set: function (v) {
  1538. N = v;
  1539. }},1,1);
  1540. J = parseInt(N,Radix);
  1541. Result = !isNaN(J);
  1542. if (Result) res.set(Math.floor(J));
  1543. return Result;
  1544. };
  1545. this.StrToInt = function (S) {
  1546. var Result = 0;
  1547. var R = 0;
  1548. if (!$mod.TryStrToInt$1(S,{get: function () {
  1549. return R;
  1550. }, set: function (v) {
  1551. R = v;
  1552. }})) throw $mod.EConvertError.$create("CreateFmt",[pas.RTLConsts.SErrInvalidInteger,[S]]);
  1553. Result = R;
  1554. return Result;
  1555. };
  1556. var HexDigits = "0123456789ABCDEF";
  1557. this.IntToHex = function (Value, Digits) {
  1558. var Result = "";
  1559. if (Digits === 0) Digits = 1;
  1560. Result = "";
  1561. while (Value > 0) {
  1562. Result = HexDigits.charAt(((Value & 15) + 1) - 1) + Result;
  1563. Value = Value >>> 4;
  1564. };
  1565. while (Result.length < Digits) Result = "0" + Result;
  1566. return Result;
  1567. };
  1568. this.TFloatFormat = {"0": "ffFixed", ffFixed: 0, "1": "ffGeneral", ffGeneral: 1, "2": "ffExponent", ffExponent: 2, "3": "ffNumber", ffNumber: 3, "4": "ffCurrency", ffCurrency: 4};
  1569. this.FloatToStrF = function (Value, format, Precision, Digits) {
  1570. var Result = "";
  1571. var DS = "";
  1572. DS = $mod.DecimalSeparator;
  1573. var $tmp1 = format;
  1574. if ($tmp1 === $mod.TFloatFormat.ffGeneral) {
  1575. Result = $impl.FormatGeneralFloat(Value,Precision,DS)}
  1576. else if ($tmp1 === $mod.TFloatFormat.ffExponent) {
  1577. Result = $impl.FormatExponentFloat(Value,Precision,Digits,DS)}
  1578. else if ($tmp1 === $mod.TFloatFormat.ffFixed) {
  1579. Result = $impl.FormatFixedFloat(Value,Digits,DS)}
  1580. else if ($tmp1 === $mod.TFloatFormat.ffNumber) {
  1581. Result = $impl.FormatNumberFloat(Value,Digits,DS,$mod.ThousandSeparator)}
  1582. else if ($tmp1 === $mod.TFloatFormat.ffCurrency) Result = $impl.FormatNumberCurrency(Value * 10000,Digits,DS,$mod.ThousandSeparator);
  1583. if (((format !== $mod.TFloatFormat.ffCurrency) && (Result.length > 1)) && (Result.charAt(0) === "-")) $impl.RemoveLeadingNegativeSign({get: function () {
  1584. return Result;
  1585. }, set: function (v) {
  1586. Result = v;
  1587. }},DS);
  1588. return Result;
  1589. };
  1590. this.TryStrToFloat = function (S, res) {
  1591. var Result = false;
  1592. var J = undefined;
  1593. var N = "";
  1594. N = S;
  1595. if ($mod.ThousandSeparator !== "") N = $mod.StringReplace(N,$mod.ThousandSeparator,"",rtl.createSet($mod.TStringReplaceFlag.rfReplaceAll));
  1596. if ($mod.DecimalSeparator !== ".") N = $mod.StringReplace(N,$mod.DecimalSeparator,".",{});
  1597. J = parseFloat(N);
  1598. Result = !isNaN(J);
  1599. if (Result) res.set(rtl.getNumber(J));
  1600. return Result;
  1601. };
  1602. this.StrToFloat = function (S) {
  1603. var Result = 0.0;
  1604. if (!$mod.TryStrToFloat(S,{get: function () {
  1605. return Result;
  1606. }, set: function (v) {
  1607. Result = v;
  1608. }})) throw $mod.EConvertError.$create("CreateFmt",[pas.RTLConsts.SErrInvalidFloat,[S]]);
  1609. return Result;
  1610. };
  1611. this.DecimalSeparator = ".";
  1612. this.ThousandSeparator = "";
  1613. rtl.createClass($mod,"TFormatSettings",pas.System.TObject,function () {
  1614. this.GetThousandSeparator = function () {
  1615. var Result = "";
  1616. Result = $mod.ThousandSeparator;
  1617. return Result;
  1618. };
  1619. });
  1620. this.FormatSettings = null;
  1621. this.CurrencyFormat = 0;
  1622. this.NegCurrFormat = 0;
  1623. this.CurrencyDecimals = 2;
  1624. this.CurrencyString = "$";
  1625. $mod.$init = function () {
  1626. $mod.FormatSettings = $mod.TFormatSettings.$create("Create");
  1627. };
  1628. },null,function () {
  1629. "use strict";
  1630. var $mod = this;
  1631. var $impl = $mod.$impl;
  1632. $impl.feInvalidFormat = 1;
  1633. $impl.feMissingArgument = 2;
  1634. $impl.feInvalidArgIndex = 3;
  1635. $impl.DoFormatError = function (ErrCode, fmt) {
  1636. var $tmp1 = ErrCode;
  1637. if ($tmp1 === 1) {
  1638. throw $mod.EConvertError.$create("CreateFmt",[pas.RTLConsts.SInvalidFormat,[fmt]])}
  1639. else if ($tmp1 === 2) {
  1640. throw $mod.EConvertError.$create("CreateFmt",[pas.RTLConsts.SArgumentMissing,[fmt]])}
  1641. else if ($tmp1 === 3) throw $mod.EConvertError.$create("CreateFmt",[pas.RTLConsts.SInvalidArgIndex,[fmt]]);
  1642. };
  1643. $impl.maxdigits = 15;
  1644. $impl.ReplaceDecimalSep = function (S, DS) {
  1645. var Result = "";
  1646. var P = 0;
  1647. P = pas.System.Pos(".",S);
  1648. if (P > 0) {
  1649. Result = (pas.System.Copy(S,1,P - 1) + DS) + pas.System.Copy(S,P + 1,S.length - P)}
  1650. else Result = S;
  1651. return Result;
  1652. };
  1653. $impl.FormatGeneralFloat = function (Value, Precision, DS) {
  1654. var Result = "";
  1655. var P = 0;
  1656. var PE = 0;
  1657. var Q = 0;
  1658. var Exponent = 0;
  1659. if ((Precision === -1) || (Precision > 15)) Precision = 15;
  1660. Result = rtl.floatToStr(Value,Precision + 7);
  1661. Result = $mod.TrimLeft(Result);
  1662. P = pas.System.Pos(".",Result);
  1663. if (P === 0) return Result;
  1664. PE = pas.System.Pos("E",Result);
  1665. if (PE === 0) {
  1666. Result = $impl.ReplaceDecimalSep(Result,DS);
  1667. return Result;
  1668. };
  1669. Q = PE + 2;
  1670. Exponent = 0;
  1671. while (Q <= Result.length) {
  1672. Exponent = ((Exponent * 10) + Result.charCodeAt(Q - 1)) - "0".charCodeAt();
  1673. Q += 1;
  1674. };
  1675. if (Result.charAt((PE + 1) - 1) === "-") Exponent = -Exponent;
  1676. if (((P + Exponent) < PE) && (Exponent > -6)) {
  1677. Result = rtl.strSetLength(Result,PE - 1);
  1678. if (Exponent >= 0) {
  1679. for (var $l1 = 0, $end2 = Exponent - 1; $l1 <= $end2; $l1++) {
  1680. Q = $l1;
  1681. Result = rtl.setCharAt(Result,P - 1,Result.charAt((P + 1) - 1));
  1682. P += 1;
  1683. };
  1684. Result = rtl.setCharAt(Result,P - 1,".");
  1685. P = 1;
  1686. if (Result.charAt(P - 1) === "-") P += 1;
  1687. while (((Result.charAt(P - 1) === "0") && (P < Result.length)) && (pas.System.Copy(Result,P + 1,DS.length) !== DS)) pas.System.Delete({get: function () {
  1688. return Result;
  1689. }, set: function (v) {
  1690. Result = v;
  1691. }},P,1);
  1692. } else {
  1693. pas.System.Insert(pas.System.Copy("00000",1,-Exponent),{get: function () {
  1694. return Result;
  1695. }, set: function (v) {
  1696. Result = v;
  1697. }},P - 1);
  1698. Result = rtl.setCharAt(Result,(P - Exponent) - 1,Result.charAt(((P - Exponent) - 1) - 1));
  1699. Result = rtl.setCharAt(Result,P - 1,".");
  1700. if (Exponent !== -1) Result = rtl.setCharAt(Result,((P - Exponent) - 1) - 1,"0");
  1701. };
  1702. Q = Result.length;
  1703. while ((Q > 0) && (Result.charAt(Q - 1) === "0")) Q -= 1;
  1704. if (Result.charAt(Q - 1) === ".") Q -= 1;
  1705. if ((Q === 0) || ((Q === 1) && (Result.charAt(0) === "-"))) {
  1706. Result = "0"}
  1707. else Result = rtl.strSetLength(Result,Q);
  1708. } else {
  1709. while (Result.charAt((PE - 1) - 1) === "0") {
  1710. pas.System.Delete({get: function () {
  1711. return Result;
  1712. }, set: function (v) {
  1713. Result = v;
  1714. }},PE - 1,1);
  1715. PE -= 1;
  1716. };
  1717. if (Result.charAt((PE - 1) - 1) === DS) {
  1718. pas.System.Delete({get: function () {
  1719. return Result;
  1720. }, set: function (v) {
  1721. Result = v;
  1722. }},PE - 1,1);
  1723. PE -= 1;
  1724. };
  1725. if (Result.charAt((PE + 1) - 1) === "+") {
  1726. pas.System.Delete({get: function () {
  1727. return Result;
  1728. }, set: function (v) {
  1729. Result = v;
  1730. }},PE + 1,1)}
  1731. else PE += 1;
  1732. while (Result.charAt((PE + 1) - 1) === "0") pas.System.Delete({get: function () {
  1733. return Result;
  1734. }, set: function (v) {
  1735. Result = v;
  1736. }},PE + 1,1);
  1737. };
  1738. Result = $impl.ReplaceDecimalSep(Result,DS);
  1739. return Result;
  1740. };
  1741. $impl.FormatExponentFloat = function (Value, Precision, Digits, DS) {
  1742. var Result = "";
  1743. var P = 0;
  1744. DS = $mod.DecimalSeparator;
  1745. if ((Precision === -1) || (Precision > 15)) Precision = 15;
  1746. Result = rtl.floatToStr(Value,Precision + 7);
  1747. while (Result.charAt(0) === " ") pas.System.Delete({get: function () {
  1748. return Result;
  1749. }, set: function (v) {
  1750. Result = v;
  1751. }},1,1);
  1752. P = pas.System.Pos("E",Result);
  1753. if (P === 0) {
  1754. Result = $impl.ReplaceDecimalSep(Result,DS);
  1755. return Result;
  1756. };
  1757. P += 2;
  1758. if (Digits > 4) Digits = 4;
  1759. Digits = ((Result.length - P) - Digits) + 1;
  1760. if (Digits < 0) {
  1761. pas.System.Insert(pas.System.Copy("0000",1,-Digits),{get: function () {
  1762. return Result;
  1763. }, set: function (v) {
  1764. Result = v;
  1765. }},P)}
  1766. else while ((Digits > 0) && (Result.charAt(P - 1) === "0")) {
  1767. pas.System.Delete({get: function () {
  1768. return Result;
  1769. }, set: function (v) {
  1770. Result = v;
  1771. }},P,1);
  1772. if (P > Result.length) {
  1773. pas.System.Delete({get: function () {
  1774. return Result;
  1775. }, set: function (v) {
  1776. Result = v;
  1777. }},P - 2,2);
  1778. break;
  1779. };
  1780. Digits -= 1;
  1781. };
  1782. Result = $impl.ReplaceDecimalSep(Result,DS);
  1783. return Result;
  1784. };
  1785. $impl.FormatFixedFloat = function (Value, Digits, DS) {
  1786. var Result = "";
  1787. if (Digits === -1) {
  1788. Digits = 2}
  1789. else if (Digits > 18) Digits = 18;
  1790. Result = rtl.floatToStr(Value,0,Digits);
  1791. if ((Result !== "") && (Result.charAt(0) === " ")) pas.System.Delete({get: function () {
  1792. return Result;
  1793. }, set: function (v) {
  1794. Result = v;
  1795. }},1,1);
  1796. Result = $impl.ReplaceDecimalSep(Result,DS);
  1797. return Result;
  1798. };
  1799. $impl.FormatNumberFloat = function (Value, Digits, DS, TS) {
  1800. var Result = "";
  1801. var P = 0;
  1802. if (Digits === -1) {
  1803. Digits = 2}
  1804. else if (Digits > 15) Digits = 15;
  1805. Result = rtl.floatToStr(Value,0,Digits);
  1806. if ((Result !== "") && (Result.charAt(0) === " ")) pas.System.Delete({get: function () {
  1807. return Result;
  1808. }, set: function (v) {
  1809. Result = v;
  1810. }},1,1);
  1811. P = pas.System.Pos(".",Result);
  1812. Result = $impl.ReplaceDecimalSep(Result,DS);
  1813. P -= 3;
  1814. if ((TS !== "") && (TS !== "\x00")) while (P > 1) {
  1815. if (Result.charAt((P - 1) - 1) !== "-") pas.System.Insert(TS,{get: function () {
  1816. return Result;
  1817. }, set: function (v) {
  1818. Result = v;
  1819. }},P);
  1820. P -= 3;
  1821. };
  1822. return Result;
  1823. };
  1824. $impl.RemoveLeadingNegativeSign = function (AValue, DS) {
  1825. var Result = false;
  1826. var i = 0;
  1827. var TS = "";
  1828. var StartPos = 0;
  1829. Result = false;
  1830. StartPos = 2;
  1831. TS = $mod.ThousandSeparator;
  1832. for (var $l1 = StartPos, $end2 = AValue.get().length; $l1 <= $end2; $l1++) {
  1833. i = $l1;
  1834. Result = (AValue.get().charCodeAt(i - 1) in rtl.createSet(48,DS.charCodeAt(),69,43)) || (AValue.get() === TS);
  1835. if (!Result) break;
  1836. };
  1837. if (Result) pas.System.Delete(AValue,1,1);
  1838. return Result;
  1839. };
  1840. $impl.FormatNumberCurrency = function (Value, Digits, DS, TS) {
  1841. var Result = "";
  1842. var Negative = false;
  1843. var P = 0;
  1844. if (Digits === -1) {
  1845. Digits = $mod.CurrencyDecimals}
  1846. else if (Digits > 18) Digits = 18;
  1847. Result = rtl.spaceLeft("" + Value,0);
  1848. Negative = Result.charAt(0) === "-";
  1849. if (Negative) pas.System.Delete({get: function () {
  1850. return Result;
  1851. }, set: function (v) {
  1852. Result = v;
  1853. }},1,1);
  1854. P = pas.System.Pos(".",Result);
  1855. if (P !== 0) {
  1856. Result = $impl.ReplaceDecimalSep(Result,DS)}
  1857. else P = Result.length + 1;
  1858. P -= 3;
  1859. while (P > 1) {
  1860. if ($mod.ThousandSeparator !== "\x00") pas.System.Insert($mod.FormatSettings.GetThousandSeparator(),{get: function () {
  1861. return Result;
  1862. }, set: function (v) {
  1863. Result = v;
  1864. }},P);
  1865. P -= 3;
  1866. };
  1867. if ((Result.length > 1) && Negative) Negative = !$impl.RemoveLeadingNegativeSign({get: function () {
  1868. return Result;
  1869. }, set: function (v) {
  1870. Result = v;
  1871. }},DS);
  1872. if (!Negative) {
  1873. var $tmp1 = $mod.CurrencyFormat;
  1874. if ($tmp1 === 0) {
  1875. Result = $mod.CurrencyString + Result}
  1876. else if ($tmp1 === 1) {
  1877. Result = Result + $mod.CurrencyString}
  1878. else if ($tmp1 === 2) {
  1879. Result = ($mod.CurrencyString + " ") + Result}
  1880. else if ($tmp1 === 3) Result = (Result + " ") + $mod.CurrencyString;
  1881. } else {
  1882. var $tmp2 = $mod.NegCurrFormat;
  1883. if ($tmp2 === 0) {
  1884. Result = (("(" + $mod.CurrencyString) + Result) + ")"}
  1885. else if ($tmp2 === 1) {
  1886. Result = ("-" + $mod.CurrencyString) + Result}
  1887. else if ($tmp2 === 2) {
  1888. Result = ($mod.CurrencyString + "-") + Result}
  1889. else if ($tmp2 === 3) {
  1890. Result = ($mod.CurrencyString + Result) + "-"}
  1891. else if ($tmp2 === 4) {
  1892. Result = (("(" + Result) + $mod.CurrencyString) + ")"}
  1893. else if ($tmp2 === 5) {
  1894. Result = ("-" + Result) + $mod.CurrencyString}
  1895. else if ($tmp2 === 6) {
  1896. Result = (Result + "-") + $mod.CurrencyString}
  1897. else if ($tmp2 === 7) {
  1898. Result = (Result + $mod.CurrencyString) + "-"}
  1899. else if ($tmp2 === 8) {
  1900. Result = (("-" + Result) + " ") + $mod.CurrencyString}
  1901. else if ($tmp2 === 9) {
  1902. Result = (("-" + $mod.CurrencyString) + " ") + Result}
  1903. else if ($tmp2 === 10) {
  1904. Result = ((Result + " ") + $mod.CurrencyString) + "-"}
  1905. else if ($tmp2 === 11) {
  1906. Result = (($mod.CurrencyString + " ") + Result) + "-"}
  1907. else if ($tmp2 === 12) {
  1908. Result = (($mod.CurrencyString + " ") + "-") + Result}
  1909. else if ($tmp2 === 13) {
  1910. Result = ((Result + "-") + " ") + $mod.CurrencyString}
  1911. else if ($tmp2 === 14) {
  1912. Result = ((("(" + $mod.CurrencyString) + " ") + Result) + ")"}
  1913. else if ($tmp2 === 15) Result = ((("(" + Result) + " ") + $mod.CurrencyString) + ")";
  1914. };
  1915. if (TS === "") ;
  1916. return Result;
  1917. };
  1918. $impl.RESpecials = "([\\[\\]\\(\\)\\\\\\.\\*])";
  1919. });
  1920. rtl.module("math",["System","SysUtils"],function () {
  1921. "use strict";
  1922. var $mod = this;
  1923. this.DegToRad = function (deg) {
  1924. var Result = 0.0;
  1925. Result = deg * (Math.PI / 180.0);
  1926. return Result;
  1927. };
  1928. });
  1929. rtl.module("Mat4",["System","browserconsole","JS","math"],function () {
  1930. "use strict";
  1931. var $mod = this;
  1932. var $impl = $mod.$impl;
  1933. rtl.createClass($mod,"TMat4",pas.System.TObject,function () {
  1934. this.$init = function () {
  1935. pas.System.TObject.$init.call(this);
  1936. this.RawComponents = rtl.arraySetLength(null,0.0,4,4);
  1937. };
  1938. this.$final = function () {
  1939. this.RawComponents = undefined;
  1940. pas.System.TObject.$final.call(this);
  1941. };
  1942. this.Identity = function () {
  1943. this.RawComponents[0][0] = 1.0;
  1944. this.RawComponents[0][1] = 0.0;
  1945. this.RawComponents[0][2] = 0.0;
  1946. this.RawComponents[0][3] = 0.0;
  1947. this.RawComponents[1][0] = 0.0;
  1948. this.RawComponents[1][1] = 1.0;
  1949. this.RawComponents[1][2] = 0.0;
  1950. this.RawComponents[1][3] = 0.0;
  1951. this.RawComponents[2][0] = 0.0;
  1952. this.RawComponents[2][1] = 0.0;
  1953. this.RawComponents[2][2] = 1.0;
  1954. this.RawComponents[2][3] = 0.0;
  1955. this.RawComponents[3][0] = 0.0;
  1956. this.RawComponents[3][1] = 0.0;
  1957. this.RawComponents[3][2] = 0.0;
  1958. this.RawComponents[3][3] = 1.0;
  1959. };
  1960. this.Translate = function (tx, ty, tz) {
  1961. this.RawComponents[0][0] = 1.0;
  1962. this.RawComponents[0][1] = 0.0;
  1963. this.RawComponents[0][2] = 0.0;
  1964. this.RawComponents[0][3] = 0.0;
  1965. this.RawComponents[1][0] = 0.0;
  1966. this.RawComponents[1][1] = 1.0;
  1967. this.RawComponents[1][2] = 0.0;
  1968. this.RawComponents[1][3] = 0.0;
  1969. this.RawComponents[2][0] = 0.0;
  1970. this.RawComponents[2][1] = 0.0;
  1971. this.RawComponents[2][2] = 1.0;
  1972. this.RawComponents[2][3] = 0.0;
  1973. this.RawComponents[3][0] = tx;
  1974. this.RawComponents[3][1] = ty;
  1975. this.RawComponents[3][2] = tz;
  1976. this.RawComponents[3][3] = 1.0;
  1977. };
  1978. this.RotateY = function (Angle) {
  1979. $mod.SinCos(Angle,{a: 0, p: this.RawComponents[2], get: function () {
  1980. return this.p[this.a];
  1981. }, set: function (v) {
  1982. this.p[this.a] = v;
  1983. }},{a: 0, p: this.RawComponents[0], get: function () {
  1984. return this.p[this.a];
  1985. }, set: function (v) {
  1986. this.p[this.a] = v;
  1987. }});
  1988. this.RawComponents[0][1] = 0.0;
  1989. this.RawComponents[0][2] = -this.RawComponents[2][0];
  1990. this.RawComponents[0][3] = 0.0;
  1991. this.RawComponents[1][0] = 0.0;
  1992. this.RawComponents[1][1] = 1.0;
  1993. this.RawComponents[1][2] = 0.0;
  1994. this.RawComponents[1][3] = 0.0;
  1995. this.RawComponents[2][1] = 0.0;
  1996. this.RawComponents[2][2] = this.RawComponents[0][0];
  1997. this.RawComponents[2][3] = 0.0;
  1998. this.RawComponents[3][0] = 0.0;
  1999. this.RawComponents[3][1] = 0.0;
  2000. this.RawComponents[3][2] = 0.0;
  2001. this.RawComponents[3][3] = 1.0;
  2002. };
  2003. this.Perspective = function (fovy, Aspect, zNear, zFar) {
  2004. var Sine = 0.0;
  2005. var Cotangent = 0.0;
  2006. var ZDelta = 0.0;
  2007. var Radians = 0.0;
  2008. Radians = (fovy * 0.5) * 0.017453292519944444;
  2009. ZDelta = zFar - zNear;
  2010. Sine = Math.sin(Radians);
  2011. if (!(((ZDelta === 0) || (Sine === 0)) || (Aspect === 0))) {
  2012. Cotangent = Math.cos(Radians) / Sine;
  2013. this.RawComponents = $impl.Matrix4x4Identity.RawComponents.slice(0);
  2014. this.RawComponents[0][0] = Cotangent / Aspect;
  2015. this.RawComponents[1][1] = Cotangent;
  2016. this.RawComponents[2][2] = -(zFar + zNear) / ZDelta;
  2017. this.RawComponents[2][3] = -1 - 0;
  2018. this.RawComponents[3][2] = -((2.0 * zNear) * zFar) / ZDelta;
  2019. this.RawComponents[3][3] = 0.0;
  2020. };
  2021. };
  2022. this.Multiply = function (m) {
  2023. var Result = null;
  2024. Result = $mod.TMat4.$create("Identity");
  2025. 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]);
  2026. 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]);
  2027. 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]);
  2028. 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]);
  2029. 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]);
  2030. 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]);
  2031. 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]);
  2032. 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]);
  2033. 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]);
  2034. 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]);
  2035. 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]);
  2036. 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]);
  2037. 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]);
  2038. 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]);
  2039. 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]);
  2040. 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]);
  2041. return Result;
  2042. };
  2043. this.Inverse = function () {
  2044. var Result = null;
  2045. var t0 = 0.0;
  2046. var t4 = 0.0;
  2047. var t8 = 0.0;
  2048. var t12 = 0.0;
  2049. var d = 0.0;
  2050. 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]);
  2051. 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]);
  2052. 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]);
  2053. 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]);
  2054. d = (((this.RawComponents[0][0] * t0) + (this.RawComponents[0][1] * t4)) + (this.RawComponents[0][2] * t8)) + (this.RawComponents[0][3] * t12);
  2055. Result = $mod.TMat4.$create("Identity");
  2056. if (d !== 0.0) {
  2057. d = 1.0 / d;
  2058. Result.RawComponents[0][0] = t0 * d;
  2059. 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;
  2060. 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;
  2061. 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;
  2062. Result.RawComponents[1][0] = t4 * d;
  2063. 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;
  2064. 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;
  2065. 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;
  2066. Result.RawComponents[2][0] = t8 * d;
  2067. 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;
  2068. 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;
  2069. 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;
  2070. Result.RawComponents[3][0] = t12 * d;
  2071. 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;
  2072. 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;
  2073. 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;
  2074. };
  2075. return Result;
  2076. };
  2077. this.CopyList = function () {
  2078. var Result = [];
  2079. var x = 0;
  2080. var y = 0;
  2081. var list = null;
  2082. list = new Array();
  2083. for (x = 0; x <= 3; x++) for (y = 0; y <= 3; y++) list.push(this.RawComponents[x][y]);
  2084. Result = list;
  2085. return Result;
  2086. };
  2087. });
  2088. this.SinCos = function (angle, sinus, cosinus) {
  2089. sinus.set(Math.sin(angle));
  2090. cosinus.set(Math.cos(angle));
  2091. };
  2092. $mod.$init = function () {
  2093. $impl.Matrix4x4Identity = $mod.TMat4.$create("Identity");
  2094. };
  2095. },null,function () {
  2096. "use strict";
  2097. var $mod = this;
  2098. var $impl = $mod.$impl;
  2099. $impl.PI = 3.14159265359;
  2100. $impl.DEG2RAD = 3.14159265359 / 180.0;
  2101. $impl.Matrix4x4Identity = null;
  2102. });
  2103. rtl.module("webgl",["System","JS","Web"],function () {
  2104. "use strict";
  2105. var $mod = this;
  2106. });
  2107. rtl.module("GLTypes",["System","webgl","JS","math"],function () {
  2108. "use strict";
  2109. var $mod = this;
  2110. this.TVec2 = function (s) {
  2111. if (s) {
  2112. this.x = s.x;
  2113. this.y = s.y;
  2114. } else {
  2115. this.x = 0.0;
  2116. this.y = 0.0;
  2117. };
  2118. this.$equal = function (b) {
  2119. return (this.x === b.x) && (this.y === b.y);
  2120. };
  2121. };
  2122. this.TVec3 = function (s) {
  2123. if (s) {
  2124. this.x = s.x;
  2125. this.y = s.y;
  2126. this.z = s.z;
  2127. } else {
  2128. this.x = 0.0;
  2129. this.y = 0.0;
  2130. this.z = 0.0;
  2131. };
  2132. this.$equal = function (b) {
  2133. return (this.x === b.x) && ((this.y === b.y) && (this.z === b.z));
  2134. };
  2135. };
  2136. this.V3 = function (x, y, z) {
  2137. var Result = new $mod.TVec3();
  2138. Result.x = x;
  2139. Result.y = y;
  2140. Result.z = z;
  2141. return Result;
  2142. };
  2143. this.ToFloats = function (v) {
  2144. var Result = [];
  2145. Result = rtl.arraySetLength(Result,0.0,3);
  2146. Result[0] = v.x;
  2147. Result[1] = v.y;
  2148. Result[2] = v.z;
  2149. return Result;
  2150. };
  2151. this.V2 = function (x, y) {
  2152. var Result = new $mod.TVec2();
  2153. Result.x = x;
  2154. Result.y = y;
  2155. return Result;
  2156. };
  2157. });
  2158. rtl.module("GLUtils",["System","Mat4","GLTypes","browserconsole","Web","webgl","JS","Types","math","SysUtils"],function () {
  2159. "use strict";
  2160. var $mod = this;
  2161. var $impl = $mod.$impl;
  2162. rtl.createClass($mod,"TShader",pas.System.TObject,function () {
  2163. this.$init = function () {
  2164. pas.System.TObject.$init.call(this);
  2165. this.gl = null;
  2166. this.vertexShader = null;
  2167. this.fragmentShader = null;
  2168. this.programID = null;
  2169. };
  2170. this.$final = function () {
  2171. this.gl = undefined;
  2172. this.vertexShader = undefined;
  2173. this.fragmentShader = undefined;
  2174. this.programID = undefined;
  2175. pas.System.TObject.$final.call(this);
  2176. };
  2177. this.Create$1 = function (context, vertexShaderSource, fragmentShaderSource) {
  2178. this.gl = context;
  2179. this.vertexShader = this.CreateShader(this.gl.VERTEX_SHADER,vertexShaderSource);
  2180. this.fragmentShader = this.CreateShader(this.gl.FRAGMENT_SHADER,fragmentShaderSource);
  2181. };
  2182. this.Compile = function () {
  2183. this.programID = this.gl.createProgram();
  2184. this.gl.attachShader(this.programID,this.vertexShader);
  2185. this.gl.attachShader(this.programID,this.fragmentShader);
  2186. };
  2187. this.Link = function () {
  2188. this.gl.linkProgram(this.programID);
  2189. if (!this.gl.getProgramParameter(this.programID,this.gl.LINK_STATUS)) {
  2190. $impl.Fatal(this.gl.getProgramInfoLog(this.programID));
  2191. };
  2192. };
  2193. this.Use = function () {
  2194. this.gl.useProgram(this.programID);
  2195. };
  2196. this.BindAttribLocation = function (index, name) {
  2197. this.gl.bindAttribLocation(this.programID,index,name);
  2198. };
  2199. this.SetUniformMat4 = function (name, value) {
  2200. var list = [];
  2201. list = value.CopyList();
  2202. this.gl.uniformMatrix4fv(this.GetUniformLocation(name),false,list);
  2203. $impl.GLFatal(this.gl,"gl.uniformMatrix4fv");
  2204. };
  2205. this.SetUniformVec3 = function (name, value) {
  2206. this.gl.uniform3fv(this.GetUniformLocation(name),pas.GLTypes.ToFloats(new pas.GLTypes.TVec3(value)));
  2207. $impl.GLFatal(this.gl,"gl.uniform3fv");
  2208. };
  2209. this.SetUniformFloat = function (name, value) {
  2210. this.gl.uniform1f(this.GetUniformLocation(name),value);
  2211. $impl.GLFatal(this.gl,"gl.uniform1f");
  2212. };
  2213. this.GetUniformLocation = function (name) {
  2214. var Result = null;
  2215. Result = this.gl.getUniformLocation(this.programID,name);
  2216. $impl.GLFatal(this.gl,"gl.getUniformLocation");
  2217. return Result;
  2218. };
  2219. this.CreateShader = function (theType, source) {
  2220. var Result = null;
  2221. var shader = null;
  2222. shader = this.gl.createShader(theType);
  2223. if (shader === null) $impl.Fatal("create shader failed");
  2224. this.gl.shaderSource(shader,source);
  2225. this.gl.compileShader(shader);
  2226. if (this.gl.getShaderParameter(shader,this.gl.COMPILE_STATUS)) {
  2227. return shader;
  2228. } else {
  2229. $impl.Fatal$1(this.gl.getShaderInfoLog(shader));
  2230. };
  2231. return Result;
  2232. };
  2233. });
  2234. this.TModelData = function (s) {
  2235. if (s) {
  2236. this.verticies = s.verticies;
  2237. this.indicies = s.indicies;
  2238. this.floatsPerVertex = s.floatsPerVertex;
  2239. } else {
  2240. this.verticies = null;
  2241. this.indicies = null;
  2242. this.floatsPerVertex = 0;
  2243. };
  2244. this.$equal = function (b) {
  2245. return (this.verticies === b.verticies) && ((this.indicies === b.indicies) && (this.floatsPerVertex === b.floatsPerVertex));
  2246. };
  2247. };
  2248. this.kModelVertexFloats = (3 + 2) + 3;
  2249. rtl.createClass($mod,"TModel",pas.System.TObject,function () {
  2250. this.$init = function () {
  2251. pas.System.TObject.$init.call(this);
  2252. this.gl = null;
  2253. this.data = new $mod.TModelData();
  2254. this.vertexBuffer = null;
  2255. this.indexBuffer = null;
  2256. };
  2257. this.$final = function () {
  2258. this.gl = undefined;
  2259. this.data = undefined;
  2260. this.vertexBuffer = undefined;
  2261. this.indexBuffer = undefined;
  2262. pas.System.TObject.$final.call(this);
  2263. };
  2264. this.Create$1 = function (context, modelData) {
  2265. this.gl = context;
  2266. this.data = new $mod.TModelData(modelData);
  2267. this.Load();
  2268. };
  2269. this.Draw = function () {
  2270. this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);
  2271. this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer);
  2272. this.EnableAttributes();
  2273. this.gl.drawElements(this.gl.TRIANGLES,this.data.indicies.length,this.gl.UNSIGNED_SHORT,0);
  2274. this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);
  2275. this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null);
  2276. };
  2277. this.EnableAttributes = function () {
  2278. var offset = 0;
  2279. var stride = 0;
  2280. offset = 0;
  2281. stride = this.data.floatsPerVertex * $mod.GLSizeof(WebGLRenderingContext.FLOAT);
  2282. this.gl.enableVertexAttribArray(0);
  2283. this.gl.vertexAttribPointer(0,3,this.gl.FLOAT,false,stride,offset);
  2284. offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 3;
  2285. this.gl.enableVertexAttribArray(1);
  2286. this.gl.vertexAttribPointer(1,2,this.gl.FLOAT,false,stride,offset);
  2287. offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 2;
  2288. this.gl.enableVertexAttribArray(2);
  2289. this.gl.vertexAttribPointer(2,3,this.gl.FLOAT,false,stride,offset);
  2290. offset += $mod.GLSizeof(WebGLRenderingContext.FLOAT) * 3;
  2291. };
  2292. this.Load = function () {
  2293. this.indexBuffer = this.gl.createBuffer();
  2294. this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer);
  2295. this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.data.indicies,this.gl.STATIC_DRAW);
  2296. this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null);
  2297. this.vertexBuffer = this.gl.createBuffer();
  2298. this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);
  2299. this.gl.bufferData(this.gl.ARRAY_BUFFER,this.data.verticies,this.gl.STATIC_DRAW);
  2300. this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);
  2301. };
  2302. });
  2303. var kLineEnding = "\n";
  2304. var kSpace = " ";
  2305. this.LoadOBJFile = function (text) {
  2306. var Result = new $mod.TModelData();
  2307. var lines = [];
  2308. var parts = [];
  2309. var indices = null;
  2310. var positions = null;
  2311. var normals = null;
  2312. var textures = null;
  2313. var verticies = null;
  2314. var mesh = null;
  2315. var i = 0;
  2316. var line = null;
  2317. var vertex = new $impl.TOBJVertex();
  2318. var vertexIndex = 0;
  2319. var data = new $mod.TModelData();
  2320. var pos = new pas.GLTypes.TVec3();
  2321. var texCoord = new pas.GLTypes.TVec2();
  2322. var normal = new pas.GLTypes.TVec3();
  2323. positions = new Array();
  2324. normals = new Array();
  2325. textures = new Array();
  2326. indices = new Array();
  2327. verticies = new Array();
  2328. lines = text.split(kLineEnding);
  2329. for (var $l1 = 0, $end2 = rtl.length(lines) - 1; $l1 <= $end2; $l1++) {
  2330. i = $l1;
  2331. line = lines[i];
  2332. parts = line.split(kSpace);
  2333. if (line.startsWith("v ")) {
  2334. pos = new pas.GLTypes.TVec3(pas.GLTypes.V3(pas.SysUtils.StrToFloat(parts[1]),pas.SysUtils.StrToFloat(parts[2]),pas.SysUtils.StrToFloat(parts[3])));
  2335. positions.push(new pas.GLTypes.TVec3(pos));
  2336. vertex.position = new pas.GLTypes.TVec3(pos);
  2337. vertex.textureIndex = -1;
  2338. vertex.normalIndex = -1;
  2339. verticies.push(new pas.GLTypes.TVec3(pos));
  2340. } else if (line.startsWith("vn ")) {
  2341. normals.push(new pas.GLTypes.TVec3(pas.GLTypes.V3(pas.SysUtils.StrToFloat(parts[1]),pas.SysUtils.StrToFloat(parts[2]),pas.SysUtils.StrToFloat(parts[3]))));
  2342. } else if (line.startsWith("vt ")) {
  2343. textures.push(new pas.GLTypes.TVec2(pas.GLTypes.V2(pas.SysUtils.StrToFloat(parts[1]),1 - pas.SysUtils.StrToFloat(parts[2]))));
  2344. } else if (line.startsWith("f ")) {
  2345. $impl.ProcessFace(verticies,indices,parts[1].split("\/"));
  2346. $impl.ProcessFace(verticies,indices,parts[2].split("\/"));
  2347. $impl.ProcessFace(verticies,indices,parts[3].split("\/"));
  2348. };
  2349. };
  2350. data.floatsPerVertex = 8;
  2351. mesh = new Float32Array(data.floatsPerVertex * verticies.length);
  2352. for (var $l3 = 0, $end4 = verticies.length - 1; $l3 <= $end4; $l3++) {
  2353. i = $l3;
  2354. vertex = new $impl.TOBJVertex(rtl.getObject(verticies[i]));
  2355. vertexIndex = i * data.floatsPerVertex;
  2356. pos = new pas.GLTypes.TVec3(rtl.getObject(positions[i]));
  2357. mesh[vertexIndex + 0] = pos.x;
  2358. mesh[vertexIndex + 1] = pos.y;
  2359. mesh[vertexIndex + 2] = pos.z;
  2360. if (vertex.textureIndex !== -1) {
  2361. texCoord = new pas.GLTypes.TVec2(rtl.getObject(textures[vertex.textureIndex]));
  2362. mesh[vertexIndex + 3] = texCoord.x;
  2363. mesh[vertexIndex + 4] = texCoord.y;
  2364. } else {
  2365. mesh[vertexIndex + 3] = 0;
  2366. mesh[vertexIndex + 4] = 0;
  2367. };
  2368. if (vertex.normalIndex !== -1) {
  2369. normal = new pas.GLTypes.TVec3(rtl.getObject(normals[vertex.normalIndex]));
  2370. mesh[vertexIndex + 5] = normal.x;
  2371. mesh[vertexIndex + 6] = normal.y;
  2372. mesh[vertexIndex + 7] = normal.z;
  2373. };
  2374. };
  2375. data.verticies = mesh;
  2376. data.indicies = new Uint16Array(indices);
  2377. Result = new $mod.TModelData(data);
  2378. return Result;
  2379. };
  2380. this.GLSizeof = function (glType) {
  2381. var Result = 0;
  2382. var $tmp1 = glType;
  2383. if (($tmp1 === WebGLRenderingContext.UNSIGNED_BYTE) || ($tmp1 === WebGLRenderingContext.BYTE)) {
  2384. Result = 1}
  2385. else if (($tmp1 === WebGLRenderingContext.SHORT) || ($tmp1 === WebGLRenderingContext.UNSIGNED_SHORT)) {
  2386. Result = 2}
  2387. else if (($tmp1 === WebGLRenderingContext.INT) || ($tmp1 === WebGLRenderingContext.UNSIGNED_INT)) {
  2388. Result = 4}
  2389. else if ($tmp1 === WebGLRenderingContext.FLOAT) {
  2390. Result = 4}
  2391. else {
  2392. $impl.Fatal("GLSizeof type is invalid.");
  2393. };
  2394. return Result;
  2395. };
  2396. },null,function () {
  2397. "use strict";
  2398. var $mod = this;
  2399. var $impl = $mod.$impl;
  2400. $impl.Fatal = function (messageString) {
  2401. pas.System.Writeln("*** FATAL: ",messageString);
  2402. return;
  2403. };
  2404. $impl.Fatal$1 = function (messageString) {
  2405. pas.System.Writeln("*** FATAL: ",messageString);
  2406. return;
  2407. };
  2408. $impl.GLFatal = function (gl, messageString) {
  2409. var error = 0;
  2410. error = gl.getError();
  2411. if (error !== WebGLRenderingContext.NO_ERROR) {
  2412. var $tmp1 = error;
  2413. if ($tmp1 === WebGLRenderingContext.INVALID_VALUE) {
  2414. messageString = messageString + " (GL_INVALID_VALUE)"}
  2415. else if ($tmp1 === WebGLRenderingContext.INVALID_OPERATION) {
  2416. messageString = messageString + " (GL_INVALID_OPERATION)"}
  2417. else if ($tmp1 === WebGLRenderingContext.INVALID_ENUM) {
  2418. messageString = messageString + " (GL_INVALID_ENUM)"}
  2419. else {
  2420. messageString = (messageString + " ") + pas.SysUtils.IntToStr(error);
  2421. };
  2422. $impl.Fatal(messageString);
  2423. };
  2424. };
  2425. $impl.TOBJVertex = function (s) {
  2426. if (s) {
  2427. this.position = new pas.GLTypes.TVec3(s.position);
  2428. this.textureIndex = s.textureIndex;
  2429. this.normalIndex = s.normalIndex;
  2430. } else {
  2431. this.position = new pas.GLTypes.TVec3();
  2432. this.textureIndex = 0;
  2433. this.normalIndex = 0;
  2434. };
  2435. this.$equal = function (b) {
  2436. return this.position.$equal(b.position) && ((this.textureIndex === b.textureIndex) && (this.normalIndex === b.normalIndex));
  2437. };
  2438. };
  2439. $impl.ProcessFace = function (verticies, indices, face) {
  2440. var Result = new $impl.TOBJVertex();
  2441. var index = 0;
  2442. var vertex = new $impl.TOBJVertex();
  2443. index = pas.SysUtils.StrToInt(face[0]) - 1;
  2444. vertex = new $impl.TOBJVertex(rtl.getObject(verticies[index]));
  2445. if (index > 65536) $impl.Fatal("overflowed indices array");
  2446. if (face[1] !== "") {
  2447. vertex.textureIndex = pas.SysUtils.StrToInt(face[1]) - 1}
  2448. else vertex.textureIndex = -1;
  2449. if (face[2] !== "") {
  2450. vertex.normalIndex = pas.SysUtils.StrToInt(face[2]) - 1}
  2451. else vertex.normalIndex = -1;
  2452. indices.push(index);
  2453. verticies[index] = new $impl.TOBJVertex(vertex);
  2454. Result = new $impl.TOBJVertex(vertex);
  2455. return Result;
  2456. };
  2457. });
  2458. rtl.module("program",["System","Types","Mat4","GLUtils","GLTypes","SysUtils","browserconsole","Web","webgl","JS","math"],function () {
  2459. "use strict";
  2460. var $mod = this;
  2461. this.gl = null;
  2462. this.shader = null;
  2463. this.projTransform = null;
  2464. this.viewTransform = null;
  2465. this.modelTransform = null;
  2466. this.dragonModel = null;
  2467. this.rotateAngle = 0;
  2468. this.deltaTime = 0;
  2469. this.nextTime = 0;
  2470. this.DrawCanvas = function () {
  2471. $mod.gl.clear($mod.gl.COLOR_BUFFER_BIT + $mod.gl.DEPTH_BUFFER_BIT);
  2472. if ($mod.dragonModel !== null) {
  2473. $mod.modelTransform = pas.Mat4.TMat4.$create("Identity");
  2474. $mod.modelTransform = $mod.modelTransform.Multiply(pas.Mat4.TMat4.$create("RotateY",[pas.math.DegToRad($mod.rotateAngle)]));
  2475. $mod.shader.SetUniformMat4("modelTransform",$mod.modelTransform);
  2476. $mod.dragonModel.Draw();
  2477. };
  2478. };
  2479. this.AnimateCanvas = function (time) {
  2480. var now = 0.0;
  2481. now = time * 0.001;
  2482. $mod.deltaTime = now - $mod.nextTime;
  2483. $mod.nextTime = now;
  2484. $mod.rotateAngle = $mod.rotateAngle + (20 * $mod.deltaTime);
  2485. $mod.DrawCanvas();
  2486. window.requestAnimationFrame($mod.AnimateCanvas);
  2487. };
  2488. this.StartAnimatingCanvas = function () {
  2489. window.requestAnimationFrame($mod.AnimateCanvas);
  2490. };
  2491. rtl.createClass($mod,"TModelLoader",pas.System.TObject,function () {
  2492. this.$init = function () {
  2493. pas.System.TObject.$init.call(this);
  2494. this.gl$1 = null;
  2495. this.request = null;
  2496. };
  2497. this.$final = function () {
  2498. this.gl$1 = undefined;
  2499. this.request = undefined;
  2500. pas.System.TObject.$final.call(this);
  2501. };
  2502. this.Create$1 = function (context, path) {
  2503. this.gl$1 = context;
  2504. this.request = new XMLHttpRequest();
  2505. this.request.open("GET",path);
  2506. this.request.overrideMimeType("application\/text");
  2507. this.request.onreadystatechange = rtl.createCallback(this,"HandleLoaded");
  2508. this.request.send();
  2509. };
  2510. this.HandleLoaded = function () {
  2511. var data = new pas.GLUtils.TModelData();
  2512. if (((this.request.readyState === 4) && (this.request.status === 200)) && (this.request.responseText.length > 0)) {
  2513. data = new pas.GLUtils.TModelData(pas.GLUtils.LoadOBJFile(this.request.responseText));
  2514. $mod.dragonModel = pas.GLUtils.TModel.$create("Create$1",[this.gl$1,new pas.GLUtils.TModelData(data)]);
  2515. $mod.StartAnimatingCanvas();
  2516. };
  2517. };
  2518. });
  2519. this.canvas = null;
  2520. this.vertexShaderSource = "";
  2521. this.fragmentShaderSource = "";
  2522. $mod.$main = function () {
  2523. $mod.canvas = document.createElement("canvas");
  2524. $mod.canvas.width = 600;
  2525. $mod.canvas.height = 600;
  2526. document.body.appendChild($mod.canvas);
  2527. $mod.gl = $mod.canvas.getContext("webgl");
  2528. if ($mod.gl === null) {
  2529. pas.System.Writeln("failed to load webgl!");
  2530. return;
  2531. };
  2532. $mod.vertexShaderSource = document.getElementById("vertex.glsl").textContent;
  2533. $mod.fragmentShaderSource = document.getElementById("fragment.glsl").textContent;
  2534. $mod.shader = pas.GLUtils.TShader.$create("Create$1",[$mod.gl,$mod.vertexShaderSource,$mod.fragmentShaderSource]);
  2535. $mod.shader.Compile();
  2536. $mod.shader.BindAttribLocation(0,"in_position");
  2537. $mod.shader.BindAttribLocation(1,"in_texCoord");
  2538. $mod.shader.BindAttribLocation(2,"in_normal");
  2539. $mod.shader.Link();
  2540. $mod.shader.Use();
  2541. $mod.gl.clearColor(0.9,0.9,0.9,1);
  2542. $mod.gl.viewport(0,0,$mod.canvas.width,$mod.canvas.height);
  2543. $mod.gl.clear($mod.gl.COLOR_BUFFER_BIT);
  2544. $mod.gl.enable($mod.gl.DEPTH_TEST);
  2545. $mod.gl.enable($mod.gl.BLEND);
  2546. $mod.gl.enable($mod.gl.CULL_FACE);
  2547. $mod.gl.cullFace($mod.gl.BACK);
  2548. $mod.projTransform = pas.Mat4.TMat4.$create("Perspective",[60.0,$mod.canvas.width / $mod.canvas.height,0.1,2000]);
  2549. $mod.shader.SetUniformMat4("projTransform",$mod.projTransform);
  2550. $mod.viewTransform = pas.Mat4.TMat4.$create("Identity");
  2551. $mod.viewTransform = $mod.viewTransform.Multiply(pas.Mat4.TMat4.$create("Translate",[0,-3,-20]));
  2552. $mod.shader.SetUniformMat4("viewTransform",$mod.viewTransform);
  2553. $mod.shader.SetUniformMat4("inverseViewTransform",$mod.viewTransform.Inverse());
  2554. $mod.shader.SetUniformVec3("lightPosition",new pas.GLTypes.TVec3(pas.GLTypes.V3(0,0,25)));
  2555. $mod.shader.SetUniformVec3("lightColor",new pas.GLTypes.TVec3(pas.GLTypes.V3(1,1,1)));
  2556. $mod.shader.SetUniformFloat("shineDamper",10);
  2557. $mod.shader.SetUniformFloat("reflectivity",1);
  2558. $mod.TModelLoader.$create("Create$1",[$mod.gl,"res\/dragon.obj"]);
  2559. };
  2560. });