<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nikola</title>
    <description>The latest articles on DEV Community by Nikola (@zlatnaspirala).</description>
    <link>https://dev.to/zlatnaspirala</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F257924%2F0b792620-3609-4af6-ac32-053256d50e33.jpeg</url>
      <title>DEV Community: Nikola</title>
      <link>https://dev.to/zlatnaspirala</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zlatnaspirala"/>
    <language>en</language>
    <item>
      <title>The Beast is hungry</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Sun, 16 Aug 2026 20:36:26 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/the-beast-is-hungry-5ebo</link>
      <guid>https://dev.to/zlatnaspirala/the-beast-is-hungry-5ebo</guid>
      <description>&lt;p&gt;&lt;strong&gt;matrix-engine-wgpu&lt;/strong&gt;&lt;br&gt;
Author: Nikola Lukić 📧 &lt;a href="mailto:zlatnaspirala@gmail.com"&gt;zlatnaspirala@gmail.com&lt;/a&gt; 📅 Version: 1.19.0 2026 Alias &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Beast&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfp48asjm8o1vw4wig60.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfp48asjm8o1vw4wig60.webp" alt=" " width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
WebGPU engine focus performance but also mimic major engines features but optimised to work well on mobile devices. It uses the wgpu-matrix npm package as a replacement for gl-matrix to handle model-view-projection matrices. All examples work (no heat/lag) on mobile browser (android-chrome tested) thats the point of The-Beast. Performance optimization is const WIP.&lt;/p&gt;

&lt;p&gt;Published on npm as: matrix-engine-wgpu (not always updated on last - recommended is to use github clone) From [1.18.7] ver npm package is much more stable and usable. All examples can be done by npm services not just github clone. You can also use (links tested). You can use RES like prefix for textures or objects paths. The Beast is friendly with codepen, worker physics bridge will test host origin name "is it external or not" to fix loading link. If domain is not &lt;code&gt;cross origin&lt;/code&gt; it will use local resource always.&lt;/p&gt;

&lt;p&gt;Main references about project: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend editorX&lt;/strong&gt; (&lt;em&gt;VisualScripting&lt;/em&gt;) (works in local env - desktop browsers) support list: Chrome, Edge, Opera, Firefox desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Creator&lt;/strong&gt; (TheBeast Code generator) is standalone. Can be used public but user must trust page to enter api key. Without api key no ai response. Code creator make project from task and test it direct intro same page. Code creator dont even needed to build own js bundle, just use it from watcher build on localhost:3000 by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt; For one single setup with kurento-openvidu-nodejs middleware. (I will bring back custom networking options setup with MultiRTC lib).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Done list []&lt;/strong&gt;&lt;br&gt;
✔️ Draw loop per pipeline not per mesh (PipelineManager) with share material. Power optimisation.&lt;br&gt;
✔️ Support for 3D objects and scene transformations.&lt;br&gt;
✔️ Ammo.js, cannonES &amp;amp;&amp;amp; Jolt Physics libs integration (app&amp;lt;-&amp;gt;bridge&amp;lt;-&amp;gt;worker). Physics use webworkers by default. Fixed crossOrigin worker.&lt;br&gt;
✔️ Networking with Kurento/OpenVidu/Own middleware Nodejs -&amp;gt; frontend.&lt;br&gt;
✔️ Bloom post processing.&lt;br&gt;
✔️ HZB post processing.&lt;br&gt;
✔️ Volumetric post processing.&lt;br&gt;
✔️ Scene Culling feature (see maze example).&lt;br&gt;
📦 Based on the shadowMapping sample from webgpu-samples.&lt;br&gt;
✔️ Web GUI(online) Editor [app exec graph] with Visual Scripting (Named: FlowCodexVertex).&lt;br&gt;
✔️ Web GUI(online) Editor [shader graph] with Visual Scripting (Named: FlowCodexShader).&lt;br&gt;
✔️ Dynamic shadow cast (done also for skinned meshes).&lt;br&gt;
✔️ VertexShader displacment (done also for skinned meshes), nice for water effect.&lt;br&gt;
✔️ Basic flow for AI Graph Generator - Simple tasks passed for now with ollama platform. Open account/open-source/free-service-quota.&lt;br&gt;
✔️ ProceduralMesh objectScene entity with options for vertex morph - Shadows following morph blend.&lt;br&gt;
✔️ MediaPipe implemented - dinamic loading (if not in use no loading script or any related to mediapipe)&lt;br&gt;
✔️ Remote render stream emit example (standard engine networking) and special endpoint for "wachers" tv-10.html Replace webcam stream with canvas capture - on endpoint use webRTC and video tag to preview remote render.&lt;br&gt;
✔️ Code creator AI services agent system(use engine from npm) npm run creator for '&lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;' npm run creator-backend for backend. create games from simple prompt.&lt;br&gt;
Roadmap/sync to external parts&lt;br&gt;
(Preparing API DOCs)[&lt;a href="https://github.com/zlatnaspirala/matrix-engine-wgpu/wiki/Visual-Scripting-API" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-wgpu/wiki/Visual-Scripting-API&lt;/a&gt;]&lt;br&gt;
🎯 Test linux OS -&amp;gt; Editor creates and manages files internally.&lt;br&gt;
🎯 Improve gizmo feature.&lt;br&gt;
🎯 Sync npm version and make editor posible from npm i matrix-engine-wgpu.&lt;br&gt;
🎯 Sync npm version for matrix-engine-wgpu wrapper (me-webgpu-react)[&lt;a href="https://github.com/zlatnaspirala/me-webgpu-react" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/me-webgpu-react&lt;/a&gt;]&lt;br&gt;
Add fully physics options. Soft bodies etc...&lt;/p&gt;
&lt;h2&gt;
  
  
  FluxCodexVertex Web Graph Editor 🚀 (since version 1.8.0)
&lt;/h2&gt;

&lt;p&gt;EditorX has two main parts:&lt;/p&gt;

&lt;p&gt;Frontend (./src/tools/editor)&lt;br&gt;
Backend (./src/tools/editor/backend)&lt;br&gt;
Before running anything, install dependencies with &lt;code&gt;npm i&lt;/code&gt;&lt;br&gt;
in the root folder and also inside &lt;code&gt;./src/tools/editor/backend&lt;/code&gt;&lt;br&gt;
The backend is built using Node.js 🟢&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;General Features 🧩&lt;/strong&gt;&lt;br&gt;
Editor creates and manages files internally (Windows tested only!).&lt;br&gt;
Scene container [adding objs -&amp;gt; auto save]&lt;br&gt;
SceneObject property container [selected object] [auto save]&lt;br&gt;
Assets toolbar added (bottom panel)&lt;br&gt;
Add GLB or OBJ files (also mp3) from the asset toolbox by selecting them.&lt;br&gt;
Top menu for adding primitives (Cube / Sphere) with or without physics ⚙️&lt;br&gt;
Integrated Visual Scripting system 🧠 FluxCodexVertex for program exec flow.&lt;br&gt;
Integrated Visual Scripting system 🧠 FluxCodexShader for shader.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Visual Scripting *&lt;/em&gt;– Implemented Features ✅&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Math nodes, events / custom methods, variable popup, SceneObject access&lt;/li&gt;
&lt;li&gt;Get SceneObject → set position → bind onTargetReach events
SetTexture, setMaterial,&lt;/li&gt;
&lt;li&gt;Fetch, GetArray, forEach, Print, IF, Math, compare, string operation etc...&lt;/li&gt;
&lt;li&gt;Custom func editor - Function Manager after creating use it from visual scripting.&lt;/li&gt;
&lt;li&gt;Generator physics bodies in sequence pos in choosen geometry in world pos (Pyramid, wall, in place).&lt;/li&gt;
&lt;li&gt;onDraw Event node - called on every frame.Can be multiply used and set skip value. More skip less calls.&lt;/li&gt;
&lt;li&gt;Audio reactive node Audio to pos , rot, scale or geometry or any... Outputs low, mid, high, energy and beat.&lt;/li&gt;
&lt;li&gt;Run the graph ▶️&lt;/li&gt;
&lt;li&gt;Stop the graph Just basic - clear dinamic created object and stops onDraw calls.&lt;/li&gt;
&lt;li&gt;Save graph
Saved to file direct also cached on LocalStorage
For final builds, becomes a real JS object injected into the app flow.[DONE]&lt;/li&gt;
&lt;li&gt;Export graph to JSON&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import graph from JSON&lt;br&gt;
Insert graph from JSON from generated data (ai tool)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Experimental] Generate graphs with ai tools services First working graph done with ollama platform. You need to open account on ollama platform for free quota service. Get API key and add it to the aitool config file (src\tools\editor\backend\config.js) Backend Config.js is in git ignored list. If you need to create it use this format: If not exist just create it (it's ignored).&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aiConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ollama&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;***********&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;qrok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;************&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;anthropic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;************&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;google&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;************&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For now i create graphs with simple tasks. In future it will be able to create whole scenes or simple games.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Important Notes&lt;/strong&gt;&lt;br&gt;
Visual Scripting is only available when running the engine from source&lt;br&gt;
(not from npm i matrix-engine-wgpu). You must clone or download the engine source from the GitHub repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instructions 📌&lt;/strong&gt;&lt;br&gt;
Editor use esbuild compiler but still present browserify, both works perfect.&lt;/p&gt;

&lt;p&gt;Run the editor with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run editorx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the engine root directory. EditorX is an alias for FluxCodexVertex backend part (needed three words to keep the name unique) Run the scene by pressing F6 or by clicking Run in the left panel If you delete all objects from the scene, you must refresh the page and add at least one object again Before importing a graph, delete all nodes from the FluxCodexVertex graph After deleting everything, click Save to store an empty [] array. All changes in graph must be saved manually/clicking for now 💾 (no autosave for graphs).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Beast Code Creator&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Running Standalone (but it is buildin) use engine from npm service not from src. Running from the Engine Monorepo: If you cloned the full matrix-engine-wgpu repo, run these from the engine root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run creator-install   &lt;span class="c"&gt;# First time&lt;/span&gt;
&lt;span class="c"&gt;# Or go manually:&lt;/span&gt;
&lt;span class="c"&gt;# "cd src/tools/the-beast-code-gen &lt;/span&gt;
&lt;span class="c"&gt;# npm i&lt;/span&gt;

&lt;span class="c"&gt;# Running&lt;/span&gt;
npm 
npm run creator          &lt;span class="c"&gt;# frontend&lt;/span&gt;
npm run creator-backend  &lt;span class="c"&gt;# backend (socket server)&lt;/span&gt;
API Keys: src&lt;span class="se"&gt;\t&lt;/span&gt;ools&lt;span class="se"&gt;\t&lt;/span&gt;he-beast-code-gen&lt;span class="se"&gt;\s&lt;/span&gt;rc&lt;span class="se"&gt;\c&lt;/span&gt;onfig.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From [1.18.6] version:&lt;/p&gt;

&lt;p&gt;Added code-creator AI driven by not for graphs it is for code direct. Backend: npm run creator-backend Frontend: npm run creator&lt;/p&gt;

&lt;p&gt;Code Creator part (no visual nodes - just top project code) can be public. Users must trust you! I will force local usage.&lt;/p&gt;

&lt;p&gt;Api documentation&lt;br&gt;
Build api with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;typedoc index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live: &lt;a href="https://maximumroulette.com/apps/webgpu/api-docs/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/webgpu/api-docs/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scene Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Canvas is dynamically created in JavaScript—no  element needed in HTML.&lt;/p&gt;

&lt;p&gt;Access the main scene objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or by name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSceneObjectByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sphere1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add meshes with .addMeshObj(), supporting .obj loading, unlit textures, cubes, spheres, etc.&lt;/p&gt;

&lt;p&gt;Destroy sceneObj:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeSceneObjectByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sphere1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also interest for clearing physics body and render part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroyByPrefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;towers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroyBySufix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_001&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Destroy objects become true after calling flushDestroyQueue function.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flushDestroyQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleanly destroy the scene:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroyProgram&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Camera Options&lt;/strong&gt;&lt;br&gt;
Add in args for instancing main MEWGPU class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mainCameraParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WASD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;responseCoef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access camera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCamera&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.26&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setYaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.06&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_dirtyAngle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now translation is only with WASD keyboard keys. Supported types: WASD, RPGCamera, FirstPersonCamera, cinematicCamera&lt;/p&gt;

&lt;p&gt;WASD also use 'c' and 'v' for up and down camera position.&lt;/p&gt;

&lt;p&gt;To change position dont use direct edit on position array. Use methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstPersonCamera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;movementSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collisionSystem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstPersonCamera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstPersonCamera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10.40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstPersonCamera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCamera&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setYaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.03&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.49&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_dirtyAngle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cinematic camera:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;introPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CameraPath&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;parameterization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;introPath&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onEnd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Object Position&lt;/strong&gt;&lt;br&gt;
Best way for access physics body object: app.matrixPhysics.getBodyByName(name) Return idx of body.Use that idx for any call of worker fn.&lt;/p&gt;

&lt;p&gt;Control object position:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translateByX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Teleport / set directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust movement speed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thrust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;⚠️ For physics-enabled objects, use matrixPhysics functions — .position and .rotation are not visually applied but can be read.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;from 1.11.0 physics works from webworkers getBodyByName on cleaver way return body id not body inself but all funck now use ids not real body ref. interface stay same. see examples for physics like flipper game.&lt;/p&gt;

&lt;p&gt;Example for apply physics on scene object click.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;physicsPlayground&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ray.hit.event&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ray.hit.event:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;physics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrixPhysics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// The engine instance&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBodyByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hitObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Apply Impulse up&lt;/span&gt;
  &lt;span class="c1"&gt;// physics.applyImpulse(body, new PVector(0, 5, 0));&lt;/span&gt;
  &lt;span class="c1"&gt;// 2. Set Angular Velocity&lt;/span&gt;
  &lt;span class="c1"&gt;// physics.setAngularVelocity(body, new PVector(0, 9, 9));&lt;/span&gt;
  &lt;span class="c1"&gt;// 3. Directional hit based on ray&lt;/span&gt;
  &lt;span class="c1"&gt;// const dir = e.detail.rayDirection; // assuming [x, y, z]&lt;/span&gt;
  &lt;span class="c1"&gt;// const strength = 20;&lt;/span&gt;
  &lt;span class="c1"&gt;// physics.applyImpulse(body, new PVector(&lt;/span&gt;
  &lt;span class="c1"&gt;//   dir[0] * strength,&lt;/span&gt;
  &lt;span class="c1"&gt;//   dir[1] * strength,&lt;/span&gt;
  &lt;span class="c1"&gt;//   dir[2] * strength&lt;/span&gt;
  &lt;span class="c1"&gt;// ));&lt;/span&gt;
  &lt;span class="c1"&gt;// 4. Explosion example&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hitPos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PVector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hitPoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hitPoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hitPoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hitPos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// 5. Change Materials&lt;/span&gt;
  &lt;span class="c1"&gt;// const metal = {friction: 0.4, restitution: 0.1};&lt;/span&gt;
  &lt;span class="c1"&gt;// physics.setMaterial(body, metal.friction, metal.restitution);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Object Rotation&lt;/strong&gt;&lt;br&gt;
Manual rotation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auto-rotate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop rotation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_⚠️ For physics-enabled objects, use matrixPhysics methods (e.g., .applyImpulse).&lt;br&gt;
_&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Lighting System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Matrix Engine WGPU now supports independent light entities, meaning lights are no longer tied to the camera. You can freely place and configure lights in the scene, and they will affect objects based on their type and parameters.&lt;/p&gt;

&lt;p&gt;Supported Light Types Ambient global also per material SpotLight – Emits light in a cone shape with configurable cutoff angles.&lt;/p&gt;

&lt;p&gt;(Planned: PointLight)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Supports multiple lights ✅ Shadow-ready&lt;/p&gt;
&lt;h2&gt;
  
  
  Important Required to be added manual:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLight&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Access lights with array lightContainer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lightContainer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSceneLightByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Materials&lt;/strong&gt;&lt;br&gt;
With last glb feature materials become part of engine also.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;standard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;water&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mirror&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Standard is fully supported with lights shadow cast down (not for anims yet)&lt;br&gt;
Pong&lt;br&gt;
Power - no shadows cast&lt;br&gt;
Mirror is env map. If you use mirror you must pass arg&lt;br&gt;
Dark&lt;br&gt;
water&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Also for addMeshObj&lt;/span&gt;
&lt;span class="nx"&gt;TEST_ANIM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addGlbObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;power&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;glbFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Mirror example&lt;/span&gt;
&lt;span class="nx"&gt;TEST_ANIM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addGlbObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mirror&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;envMapParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;baseColorMix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mirrorTint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;     &lt;span class="c1"&gt;// Slight cool tint&lt;/span&gt;
    &lt;span class="na"&gt;reflectivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;// 25% reflection blend&lt;/span&gt;
    &lt;span class="na"&gt;illuminateColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Soft cyan&lt;/span&gt;
    &lt;span class="na"&gt;illuminateStrength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// Gentle rim&lt;/span&gt;
    &lt;span class="na"&gt;illuminatePulse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// No pulse (static)&lt;/span&gt;
    &lt;span class="na"&gt;fresnelPower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;// Medium-sharp edge&lt;/span&gt;
    &lt;span class="na"&gt;envLodBias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;usePlanarReflection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// ✅ FOr now only false - Env map mode&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;glbFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;Mirror&lt;/span&gt; &lt;span class="nx"&gt;mat&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;// Access some object with mirror mat&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;writeParamsMirror&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseColorMix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mirrorTint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;reflectivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;illuminateColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;illuminateStrength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;11.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;illuminatePulse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fresnelPower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;envLodBias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;usePlanarReflection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change only textures (no recreation of pipeline)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;loadTex0&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;res/icons/editor/chatgpt-gen-bg.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;changeTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;texture0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup Blend (For water mat use blend!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;setBlend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples for setup water params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;updateWaterParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Deep: navy&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Shallow: blue&lt;/span&gt;
  &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Wave speed: fast continuous&lt;/span&gt;
  &lt;span class="mf"&gt;1.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Wave scale: rolling waves&lt;/span&gt;
  &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Wave height: tall active waves&lt;/span&gt;
  &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Fresnel: strong&lt;/span&gt;
  &lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Specular: soft highlights&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;updateWaterParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Deep: medium blue&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Shallow: bright cyan&lt;/span&gt;
  &lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Wave speed: gentle continuous (changed from 0.6)&lt;/span&gt;
  &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Wave scale: smooth ripples (changed from 5.0)&lt;/span&gt;
  &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Wave height: visible movement&lt;/span&gt;
  &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Fresnel: moderate reflection&lt;/span&gt;
  &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Specular: sharp sparkles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Effect (Standalone pipeline draw subsystem)&lt;br&gt;
Activation for prebuild(buildin) effects&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TEST_ANIM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addGlbObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;pointerEffect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;flameEffect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;flameEmitter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;glbFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Access in runtime :&lt;/span&gt;
&lt;span class="c1"&gt;// app.mainRenderBundle[0].effects&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use random for creation than when you find perfect crazzy fancy case just collect input data see: &lt;a href="https://gist.github.com/zlatnaspirala/8758bcfb8be81d65c2c428e222abbef2" rel="noopener noreferrer"&gt;https://gist.github.com/zlatnaspirala/8758bcfb8be81d65c2c428e222abbef2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bloom post processing&lt;/strong&gt;&lt;br&gt;
Activete with :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activateBloomEffect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manipulate with app.bloomPass: setKnee setIntensity setThreshold setBlurRadius.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Volumetric effect&lt;/strong&gt;&lt;br&gt;
Call from app app.activateVolumetricEffect() !Note volumetric works only if bloom is activated. Bloom can work alone.&lt;/p&gt;

&lt;p&gt;Passing arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activateVolumetricEffect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;density&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.03&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;scatterStrength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;heightFalloff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lightColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Object Interaction (Raycasting)&lt;/strong&gt;&lt;br&gt;
Manual raycast example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WASD&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// let camera = app.getCamera();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rayOrigin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rayDirection&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRayFromMouse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;rayIntersectsSphere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;rayOrigin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;rayDirection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raycast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Object clicked:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Automatic raycast listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;addRaycastListener&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Must be app.canvas or [Program name].canvas&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ray.hit.event&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ray hit:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hitObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Engine also exports (box):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;addRaycastsAABBListener&lt;/span&gt;
&lt;span class="nx"&gt;rayIntersectsAABB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;computeAABB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;computeWorldVertsAndAABB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How to Load .obj Models&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MatrixEngineWGPU&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/world.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;downloadMeshes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/engine/loader-obj.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MatrixEngineWGPU&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;useSingleRenderPass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;canvasSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fullscreen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mainCameraParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WASD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;responseCoef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PhysicsReady&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;downloadMeshes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;welcomeText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/meshes/blender/piramyd.obj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;armor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/meshes/obj/armor.obj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;sphere&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/meshes/blender/sphere.obj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cube&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/meshes/blender/cube.obj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;onLoadObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onLoadObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meshes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myLoadedMeshes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;meshes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;meshes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`%c Loaded obj: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LOG_MATRIX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMeshObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;texturesPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/textures/cube-g1-extra_low.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CubePhysics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;meshes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cube&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMeshObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;texturesPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/textures/cube-g1-extra_low.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SpherePhysics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;meshes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sphere&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sphere&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔁 Load OBJ Sequence Animation&lt;/strong&gt;&lt;br&gt;
This example shows how to load and animate a sequence of .obj files to simulate mesh-based animation (e.g. walking character).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MatrixEngineWGPU&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../src/world.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;downloadMeshes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;makeObjSeqArg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../src/engine/loader-obj.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOG_MATRIX&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../src/engine/utils.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;loadObjsSequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;loadObjFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MatrixEngineWGPU&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;useSingleRenderPass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;canvasSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fullscreen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;mainCameraParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WASD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;responseCoef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PhysicsReady&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;downloadMeshes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nf"&gt;makeObjSeqArg&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swat-walk-pistol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;res/meshes/objs-sequence/swat-walk-pistol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;}),&lt;/span&gt;
          &lt;span class="nx"&gt;onLoadObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onLoadObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`%c Loaded objs: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LOG_MATRIX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;objAnim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swat-walk-pistol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;meshList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;currentAni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;animations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;walk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;walkPistol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nx"&gt;loadObjFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMeshObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;texturesPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/textures/cube-g1-extra_low.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swat-walk-pistol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;objAnim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;objAnim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;objAnim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;walk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;loadObjFile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;💡 GLB binary loading bvh(rig)animations.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See examples glb-loader.js (build with npm run glb-loader)&lt;br&gt;
Next update materials improvements!&lt;br&gt;
Light affect just for first frame or t-pose.&lt;br&gt;
For npm service import uploadGLBModel.&lt;br&gt;
From 1.6.0 glb support multi skinned mesh + mutli primitives cases.&lt;/p&gt;

&lt;p&gt;Limitation: glb loader not handled for non animation case. Use obj loader for static mesh.&lt;/p&gt;

&lt;p&gt;Must powerfull call is new class MEMeshObjInstances. MEMeshObj is good now for optimised call(less conditionals). You can add instanced draws and modify basic color for each individualy also transformation good for fantazy or any game dev.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;glbFile01&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;uploadGLBModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addGlbObjInctance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;standard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useTextureFromGlb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;texturesPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/meshes/glb/textures/mutant_origin.webp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;raycast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;pointerEffect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;glbFile01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// access  - index -0 is BASE MESH ! I added maxLimit = 5 you can change this from engine source.&lt;/span&gt;
&lt;span class="c1"&gt;// added lepr smoot translate , also color+.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;instanceTargets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// This recreate buffer it is not for loop call space&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainRenderBundle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;updateInstances&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ProceduralMesh&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;geoTypesForMorph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cube&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sphere&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sphere&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mobius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mobius&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;capsule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;capsule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;torus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;torus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cylinder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cylinder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;wavePlane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wavePlane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;supershape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;supershape&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pyramid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pyramid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;diamond&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diamond&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;icosahedron&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;icosahedron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;circlePlane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circlePlane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;rock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;star&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;star&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;star3d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;star3d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;littleStar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;littleStar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;flatStar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flatStar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;klein&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;klein&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;rippleSphere&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rippleSphere&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;twistedTorus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twistedTorus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tornado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tornado&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;galaxySpiral&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;galaxySpiral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Draw all buildin proceduralMesh shapes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;geoTypesForMorph&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;loadObjFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addProceduralMeshObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;rotationSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;texturesPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./res/textures/cube-g1_low.webp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;meshA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MeshMorpher&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;typeA&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;meshB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MeshMorpher&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;typeB&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`morph_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;typeA&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_to_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;typeB&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sphere&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Also works - but tested just two cube.&lt;/span&gt;
&lt;span class="c1"&gt;// need to improve and est more&lt;/span&gt;
&lt;span class="c1"&gt;// let test = MeshMorpher.compose(&lt;/span&gt;
&lt;span class="c1"&gt;//   {shape: MeshMorpher.cube(1), offset: [-2, 0, 0]},&lt;/span&gt;
&lt;span class="c1"&gt;//   {shape: MeshMorpher.cube(1), offset: [2, 0, 0]},&lt;/span&gt;
&lt;span class="c1"&gt;// );&lt;/span&gt;

&lt;span class="c1"&gt;// loadObjFile.addProceduralMeshObj({&lt;/span&gt;
&lt;span class="c1"&gt;//     material: {type: 'power'},&lt;/span&gt;
&lt;span class="c1"&gt;//     position: {x: 0 , y: 5, z: -15},&lt;/span&gt;
&lt;span class="c1"&gt;//     rotation: {x: 0, y: 0, z: 0},&lt;/span&gt;
&lt;span class="c1"&gt;//     scale: [1, 1, 1],&lt;/span&gt;
&lt;span class="c1"&gt;//     rotationSpeed: {x: 0, y: 0, z: 0},&lt;/span&gt;
&lt;span class="c1"&gt;//     texturesPaths: ['./res/textures/cube-g1_low.webp'],&lt;/span&gt;
&lt;span class="c1"&gt;//     meshA: test,&lt;/span&gt;
&lt;span class="c1"&gt;//     meshB: test,&lt;/span&gt;
&lt;span class="c1"&gt;//     name: `morph_1`,&lt;/span&gt;
&lt;span class="c1"&gt;//     physics: {&lt;/span&gt;
&lt;span class="c1"&gt;//       enabled: false,&lt;/span&gt;
&lt;span class="c1"&gt;//       geometry: "Sphere"&lt;/span&gt;
&lt;span class="c1"&gt;//     }&lt;/span&gt;
&lt;span class="c1"&gt;//   });&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Morph between two shapes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sceneObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;morphTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*callback*/&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;sceneObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;morphTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*callback*/&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📽️ Video textures&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TEST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadVideoTexture&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// video , camera  //not tested canvas2d, canvas2dinline&lt;/span&gt;
  &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;res/videos/tunel.mp4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For canvasinline attach this to arg (example for direct draw on canvas2d and passing intro webgpu pipeline):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;canvaInlineProgram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;font&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px Orbitron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`FPS: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Scenario&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Best&lt;/span&gt; &lt;span class="nx"&gt;Approach&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;------------------------------&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;----------------------------------&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Dynamic&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="nx"&gt;animation&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;`canvas.captureStream()`&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="s2"&gt;`video`&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="nx"&gt;snapshot&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;`createImageBitmap(canvas)`&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Replaying&lt;/span&gt; &lt;span class="nx"&gt;real&lt;/span&gt; &lt;span class="nx"&gt;video&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;webcam&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Direct&lt;/span&gt; &lt;span class="s2"&gt;`video`&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;&lt;br&gt;
Warn can be disabled from MECongif.logLoopError (bool). If this happen less then 15 times (Loading procces) then it is ok probably...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Draw func (err):TypeError: Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': The provided value is not of type 'GPURenderPassDescriptor'.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt;&lt;br&gt;
From 1.7.0 engine powered by networking. Used kurento&amp;amp;Openvidu server for backend. Very good for handling streams, channels etc...&lt;/p&gt;

&lt;p&gt;All you needed to start kurento and openvidu and interconnect this nodejs server &lt;a href="https://github.com/zlatnaspirala/matrix-stream/blob/main/middleware/server.js" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-stream/blob/main/middleware/server.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See example code at ./examples/games/moba/&lt;/p&gt;

&lt;p&gt;Buildin net sync basic: Let's say app is engine root object and net is networking object. webRTC tech with openvidu server middleware server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.net = new MatrixStream({
  active: true,
  domain: "maximumroulette.com",
  port: 2020,
  sessionName: "forestOfHollowBlood-free-for-all",
  resolution: "160x240",
  isDataOnly: urlQuery.camera || urlQuery.audio ? false : true,
  customData: forestOfHollowBlood.player.data,
});

// `customData` if you wanna pass some extra meta data on connection-created event
// No need always camera and mic we can use is like data signaling only.
How to use buildin network operations:

// Activate emiting remote position, on remote side adapted on scene object with same name
sceneObject.position.netObject = sceneObject[0].name;
// For now net view for rot is axis separated - cost is ok for orientaion remote pass
sceneObject.rotation.emitY = sceneObject.name;
// If you need oposite remote/local situation. For example:
// you friendly object is enemy object at remote machine that just setup another flag
sceneObject.position.netObject = sceneObject[0].name; // we still need this setup!
sceneObject.position.remoteName = sceneObjecOposite[0].name;
Use toRemote arg prop in send pass, if not it is default [] emit to all.

Intelegent emit for teams (two teams implemented). Position will be emited for teams[0] and received for uniq scene obj name. Position will be emited for teams[1] and received for oposite (eg. enemy) uniq scene obj name. In this case toRemote is overrided (Don't pass it). Used for moba project.

mesh.position.teams[0] = [connId0, connId1];
mesh.position.teams[1] = [connId2, connId3];

// emiter in core engine file
if (this.teams.length &amp;gt; 0)
  if (this.teams[0].length &amp;gt; 0)
    app.net.send({
      toRemote: this.teams[0], // default null remote conns
      sceneName: this.netObject, // origin scene name to receive
      netPos: {x: this.x, y: this.y, z: this.z},
    });
if (this.teams.length &amp;gt; 0)
  if (this.teams[1].length &amp;gt; 0)
    app.net.send({
      toRemote: this.teams[1], // default null remote conns
      remoteName: this.remoteName, // to enemy players
      sceneName: this.netObject, // now not important
      netPos: {x: this.x, y: this.y, z: this.z},
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;About URLParams&lt;/strong&gt;&lt;br&gt;
Buildin Url Param check for multiLang. MultiLang feature is also buildin options.&lt;/p&gt;

&lt;p&gt;Load multilang json file data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?lang=en
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access from code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;urlQuery.lang;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also render config can be controlled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?PHYSICS_GROUND_Y=1
?fs=true                      // Force-Fullscreen
?MAX_BONES=0                  // optimisation [use this for mobile devices]
?MAX_SPOTLIGHTS=1             // optimisation [use this for mobile devices]
?SHADOW_RES=250               // optimisation [use this for mobile devices]
?GRAVITY_Y_AXIS=10            // optimisation [use this for mobile devices]
?MOUSE_SENS: 0.01             // Works for WASD and firstPersonCamera
?TOUCH_SENS: 0.03             // Works for WASD and firstPersonCamera
?CAM_SPEED: mobile 0.1 : 0.2  // Works for WASD and firstPersonCamera
?LOAD_AFTER_CLICK_MOBILE: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it : matrix-engine-wgpu/public/examples?demo=1&amp;amp;SHADOW_RES=250&lt;/p&gt;

&lt;p&gt;If you wanna full performance on mobile devices than use in constructor: This is width of canvas inself. Value 1 is the best quality case also default if not exist.&lt;/p&gt;

&lt;p&gt;fastRender = from 0.1 to 1 - Best for mobile 0.85&lt;br&gt;
In this case FORCE_FULL_SCREEN is true by default. Pushed notification click anywhere to start the engine.&lt;/p&gt;

&lt;p&gt;Note for MAX_SPOTLIGHTS : If you wanna override values from MECOnfig or even urlParam than use in main engine arg pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MatrixEngineWGPU&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;canvasSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fullscreen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fastRender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;culling&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dontUsePhysics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;MAX_SPOTLIGHTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;MAX_BONES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mainCameraParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firstPersonCamera&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// type: 'WASD',&lt;/span&gt;
      &lt;span class="na"&gt;responseCoef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;clearColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exclude (for example floor/ground) from culling: floor.ignoreCulling = true;&lt;br&gt;
About empty.js&lt;br&gt;
Android TV or any other supported device render stream receiver&lt;br&gt;
Tech: webRTC (used standard kurento/openvidu matrixStream) Look for ./public/tv-10.html&lt;/p&gt;

&lt;p&gt;To make or build you own see android native part at: &lt;a href="https://github.com/zlatnaspirala/web-to-native/tree/master/android-tv" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/web-to-native/tree/master/android-tv&lt;/a&gt; At thie repo (cef) you can find way to port also on windows, macos or linux OS but this not priory for project. Dev help for android studio: "adb connect 192.168.0.XX:5555"&lt;/p&gt;

&lt;p&gt;We need somewhere to run standard render and use networking just with new flag (streamRender):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;streamRender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MatrixStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;maximumroulette.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sessionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tv-beast&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1920x1080&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isDataOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;streamRender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NPM Scripts&lt;/strong&gt;&lt;br&gt;
Editor use esbuild. You can use watchify to bundle JavaScript. (still good) +Migration to the ESBUILD (note: it strange becouse it is exe file) but it is popular.&lt;/p&gt;

&lt;p&gt;You can setup more games/apps in single bundle or make special end point for specific game/app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"examples"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbuild examples.js --bundle --outfile=public/examples.js --format=esm --watch"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"android-tv-cast"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbuild android-tv-cast.js --bundle --outfile=public/android-tv-cast.js --format=esm --watch"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"jamb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./examples/games/jamb/jamb.js -p [esmify --noImplicitAny] -o public/yacht.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"demo1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify demo1.js -p [esmify --noImplicitAny] -o public/app.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"empty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify empty.js -p [esmify --noImplicitAny] -o public/empty.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build.jamb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"browserify main.js -p esmify &amp;gt; public/app.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"glb-loader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./examples/glb-loader.js -p [esmify --noImplicitAny] -o public/app.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"moba"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./examples/games/moba/forestOfHollowBlood.js -p [esmify --noImplicitAny] -o public/moba-game.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"moba-menu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./examples/games/moba/start-menu.js -p [esmify --noImplicitAny] -o public/moba-menu.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build-all"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run examples | npm run main | npm run empty"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"creator-install"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm --prefix src/tools/the-beast-code-gen i"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"creator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm --prefix src/tools/the-beast-code-gen run dev"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"creator-backend"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm --prefix src/tools/the-beast-code-gen run backend"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"landpage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./examples/my-lights.js -p [esmify --noImplicitAny] -o public/landpage.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"hosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http-server ./public/ -p 3000"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"editor-landing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"watchify ./src/tools/editor/template/autogen.js -p [esmify --noImplicitAny] -o public/matrix-engine-autogen.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"editorx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cd src/tools/editor/backend &amp;amp;&amp;amp; node matrix-editor.js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;br&gt;
All resources and output go into the ./public folder — everything you need in one place. This is static file storage also all builds make outputs here.&lt;/p&gt;

&lt;p&gt;For adding new endpoint app/demo you only need to create standard html file with js script name.&lt;br&gt;
Proof of Concept&lt;br&gt;
🎲 The first full app example will be a WebGPU-powered Jamb 3d deluxe game, MOBA 'Forest of hollow blood' , flipper , NUI runner etc.&lt;/p&gt;

&lt;p&gt;MOBA game Beta version done&lt;br&gt;
Features done:&lt;br&gt;
Supporetd on mobile browsers.&lt;br&gt;
Navigation mesh&lt;br&gt;
Hero class&lt;br&gt;
GLB animations&lt;br&gt;
Automatic team selection (South vs North)&lt;br&gt;
Homebase stone (tron / enemytron)&lt;br&gt;
Invertory (construct from 2 or 3 new upgraded item)&lt;br&gt;
Videochat - stream video follow player character (remote &amp;amp; local 'one on one')&lt;/p&gt;

&lt;p&gt;💲💲💲 Invest in Forest Of Hollow Blood 1,000$ See more details at FOHB Wiki&lt;/p&gt;

&lt;p&gt;Live Demos &amp;amp; Dev Links&lt;br&gt;
&lt;a href="https://maximumroulette.com/apps/webgpu/examples.html?demo=1" rel="noopener noreferrer"&gt;Matrix-engine-wgpu Live demos&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💲💲💲 Support JAMB 3D this project on itch.io&lt;/p&gt;

&lt;p&gt;MOBA Forest Of Hollow Blood from hosted on maximumroulette.com&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codepen examples:&lt;/strong&gt;&lt;br&gt;
The Beast Cube + Fire effect + onhit changed effect configuration&lt;br&gt;
Zombie Shooter full game on codepen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019f2f4b-2ace-7c39-b304-b4028f7e5456" rel="noopener noreferrer"&gt;The Beast Cube + Fire effect + onhit changed effect configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fc918-e45f-73f4-9987-9a1599ac4a1f" rel="noopener noreferrer"&gt;Zombie Shooter full game on codepen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fc979-ef25-7fe4-8bb4-4af074fe5843" rel="noopener noreferrer"&gt;The Beast Maze + culling + collision non real physics involved&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd2c0-3b88-7562-98dd-195bc4f74e3f" rel="noopener noreferrer"&gt;The Beast - Platformer 2D demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd2fe-77c8-7860-a2b7-ee332ce29d86" rel="noopener noreferrer"&gt;The Beast - Slot Mashine, initializeSpritesForMesh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd30e-35ba-7c0c-a406-8db158bae5c7" rel="noopener noreferrer"&gt;The Beast - BVH Skeletal animations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd31d-7e1d-7149-b2e4-b82e7dd57197" rel="noopener noreferrer"&gt;The Beats - Camera texture on MorphMesh object example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd323-4e24-72bb-9456-399ce2d792ff" rel="noopener noreferrer"&gt;The Beast - Canvas2d inline draws in webGPU scene&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd339-1abb-7622-adb5-ae2e427cad29" rel="noopener noreferrer"&gt;The Beast - Cinematic Camera movement demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd33f-b64d-76f4-b136-91a5e3afdf76" rel="noopener noreferrer"&gt;The Beast - Procedural destruction demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd37a-554a-7fc8-aea8-e345f5e38caf" rel="noopener noreferrer"&gt;The Beast - Flipper JOLJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd353-5540-79ce-8d7b-12cb2d90a3a8" rel="noopener noreferrer"&gt;The Beast - Drum with balls with continius rounds of 5 numbers (JOLT Bridge)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd388-de26-71dc-a6f0-481525624b42" rel="noopener noreferrer"&gt;The Beast - Splat Color Effects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd3a0-6cd9-756c-bf77-985e2a60741e" rel="noopener noreferrer"&gt;The Beast - Gaussian splat vertex animator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd635-9e66-7795-93df-3dd7ab08414b" rel="noopener noreferrer"&gt;The Beast - Horizontal Z-buffer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/editor/zlatnaspirala/pen/019fd663-3e4e-7e1e-802f-e17f22858512" rel="noopener noreferrer"&gt;The Beast - ProceduralMesh - morphTo func&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fcam.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="759" height="380" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fcam.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="1920" height="1080" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game2.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="1920" height="1080" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game2.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game3.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="1920" height="1080" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game3.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game4.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="760" height="428" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fmmorpg-online-game4.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fearth.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="1847" height="930" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fearth.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fbvh.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img width="1859" height="976" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fzlatnaspirala%2Fmatrix-engine-wgpu%2Fblob%2Fmain%2Fnon-project-files%2Fbvh.png%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Performance for Jamb game:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F05prwkah9w138xn9cdhu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F05prwkah9w138xn9cdhu.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;br&gt;
Special licence for MOBA example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Creative Commons Attribution 4.0 International (CC BY 4.0)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are free to share and adapt this project, provided that you give appropriate credit.&lt;br&gt;
Attribution requirement:&lt;br&gt;
Include the following notice (with working link) in any distributed version or about page:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Forest Of Hollow Blood — an MOBA example made with MatrixEngineWGPU (&lt;a href="https://github.com/zlatnaspirala/matrix-engine-wgpu)" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-wgpu)&lt;/a&gt;"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Web Editor FluxCodexVertex from version [1.8.0]&lt;br&gt;
Run editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run editorx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to matrix-engine.html it is landing page for editor. After create new project or load project page will be redirect to &lt;code&gt;./public/&amp;lt;PROJECT_NAME&amp;gt;.html&lt;/code&gt; Source location : &lt;code&gt;./projects/&amp;lt;PROJECT_NAME&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;br&gt;
Create new project/ load project - only on landing page&lt;br&gt;
Create cubeMesh&lt;br&gt;
Properties box for selected sceneObj&lt;br&gt;
Events system (Create func and attach to sceneObj)&lt;br&gt;
Resource navigation&lt;br&gt;
Visual Scripting&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/note"&gt;@note&lt;/a&gt; License for fluxCodexVertex.js (MPL 2.0) Affect only this file! Just leave comment licence part in header of file.&lt;/p&gt;

&lt;p&gt;YT video promotion :&lt;/p&gt;

&lt;p&gt;About 'In fly' regime: Editor can be activated even without backend node but in that case no saves.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;License &amp;amp;&amp;amp; Credits&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Usage Note&lt;br&gt;
You may use, modify, and sell projects based on this code — just keep this notice and included references intact (whole licence paragraph - but you can always remove assets -&amp;gt; remove asset back link).&lt;/p&gt;

&lt;p&gt;Most important is reference on matrix-engine-wgpu.&lt;br&gt;
You need just to copy paste this text to about form on your web page or any other type of app.&lt;br&gt;
You can remove almost all licence for assets if you remove current assest from your project (Fork this repo - remove all required link back assets - remove assets licence)&lt;br&gt;
Attribution &amp;amp; Credits&lt;br&gt;
Engine design and scene structure inspired by: WebGPU Samples&lt;/p&gt;

&lt;p&gt;OBJ Loader adapted from: &lt;a href="http://math.hws.edu/graphicsbook/source/webgl/cube-camera.html" rel="noopener noreferrer"&gt;http://math.hws.edu/graphicsbook/source/webgl/cube-camera.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dice roll sound roll1.wav sourced from: &lt;a href="https://wavbvkery.com/dice-rolling-sound/" rel="noopener noreferrer"&gt;https://wavbvkery.com/dice-rolling-sound/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Raycasting logic and glb loader assisted by ChatGPT.&lt;/p&gt;

&lt;p&gt;GLTF Loader: &lt;a href="https://github.com/Twinklebear/webgpu-gltf" rel="noopener noreferrer"&gt;https://github.com/Twinklebear/webgpu-gltf&lt;/a&gt;, improved with chatgpt.&lt;/p&gt;

&lt;p&gt;Origin jpg (free format) source: &lt;a href="http://spiralgraphics.biz/" rel="noopener noreferrer"&gt;http://spiralgraphics.biz/&lt;/a&gt; More: &lt;a href="Https://blenderartists.org/t/is-spiral-graphics-genetica-dead/1446058"&gt;Https://blenderartists.org/t/is-spiral-graphics-genetica-dead/1446058&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://polyhaven.com/a/checkered_pavement_tiles" rel="noopener noreferrer"&gt;https://polyhaven.com/a/checkered_pavement_tiles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Music by Mykola Sosin from Pixabay&lt;/p&gt;

&lt;p&gt;Characters used from great mixamo.com -✅What you can do You can use Mixamo characters and animations royalty-free in commercial, personal, or non‑profit projects (games, films, prints, etc.).You own your creations / how you use them.No requirement to credit Adobe / Mixamo (though allowed). -🚫What you cannot do You cannot redistribute or sell the raw Mixamo character or animation files “as is” (i.e. as standalone assets) to others.You can’t use Mixamo content to create a competing library of characters / animations (i.e. you can’t just package them and sell them to others). You can’t use Mixamo’s content (or outputs) to train AI / machine learning models.&lt;/p&gt;

&lt;p&gt;Music used: BLACK FLY by Audionautix | &lt;a href="http://audionautix.com" rel="noopener noreferrer"&gt;http://audionautix.com&lt;/a&gt; Music promoted by &lt;a href="https://www.free-stock-music.com" rel="noopener noreferrer"&gt;https://www.free-stock-music.com&lt;/a&gt; Creative Commons Attribution-ShareAlike 3.0 Unported&lt;/p&gt;

&lt;p&gt;Used free assets from great &lt;a href="https://craftpix.net" rel="noopener noreferrer"&gt;https://craftpix.net&lt;/a&gt; Magic icons : &lt;a href="https://craftpix.net/freebies/free-rpg-splash-game-512x512-icons/" rel="noopener noreferrer"&gt;https://craftpix.net/freebies/free-rpg-splash-game-512x512-icons/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Hang3d zombi template - objects are downloaded from: &lt;a href="http://www.md2.sitters-electronics.nl" rel="noopener noreferrer"&gt;www.md2.sitters-electronics.nl&lt;/a&gt; Keep this "readme.md" file with files.&lt;/p&gt;

&lt;p&gt;For background music in rpg template used: Music by Dvir Silverstone from Pixabay Sound Effect by Crunchpix Studio from Pixabay Music by Emmraan from Pixabay&lt;/p&gt;

&lt;p&gt;'Ruined rock fence' (&lt;a href="https://skfb.ly/6RLwN" rel="noopener noreferrer"&gt;https://skfb.ly/6RLwN&lt;/a&gt;) by VladNeko is licensed under Creative Commons Attribution (&lt;a href="http://creativecommons.org/licenses/by/4.0/" rel="noopener noreferrer"&gt;http://creativecommons.org/licenses/by/4.0/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;"fantasy rock" (&lt;a href="https://skfb.ly/oHXAz" rel="noopener noreferrer"&gt;https://skfb.ly/oHXAz&lt;/a&gt;) by duckcracker02 is licensed under Creative Commons Attribution (&lt;a href="http://creativecommons.org/licenses/by/4.0/" rel="noopener noreferrer"&gt;http://creativecommons.org/licenses/by/4.0/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;"Fantasy Rock" (&lt;a href="https://skfb.ly/oHZSq" rel="noopener noreferrer"&gt;https://skfb.ly/oHZSq&lt;/a&gt;) by lalune is licensed under Creative Commons Attribution (&lt;a href="http://creativecommons.org/licenses/by/4.0/" rel="noopener noreferrer"&gt;http://creativecommons.org/licenses/by/4.0/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Invertory images &lt;a href="https://djinnbestiary.itch.io/ancient-oddities-vol-1-13-free-potions" rel="noopener noreferrer"&gt;https://djinnbestiary.itch.io/ancient-oddities-vol-1-13-free-potions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Dancing girl" (&lt;a href="https://skfb.ly/p7vNU" rel="noopener noreferrer"&gt;https://skfb.ly/p7vNU&lt;/a&gt;) by planetrey.com is licensed under Creative Commons Attribution (&lt;a href="http://creativecommons.org/licenses/by/4.0/" rel="noopener noreferrer"&gt;http://creativecommons.org/licenses/by/4.0/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Skeletal system by: Aidan Sanderson - from blender addson blenderKit.&lt;/p&gt;

&lt;p&gt;Title: Zombies Sound Pack - Author: artisticdude Source URL: &lt;a href="https://opengameart.org/content/zombies-sound-pack" rel="noopener noreferrer"&gt;https://opengameart.org/content/zombies-sound-pack&lt;/a&gt; License: CC0 1.0 Universal (Public Domain Dedication)&lt;/p&gt;

&lt;p&gt;Folder './public/res/bvh/' Special thanks to the CMU Graphics Lab Motion Capture Database which provided the data &lt;a href="http://mocap.cs.cmu.edu/" rel="noopener noreferrer"&gt;http://mocap.cs.cmu.edu/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BSD 3-Clause License (from WebGPU Samples)&lt;br&gt;
Full License Text&lt;/p&gt;

</description>
      <category>webgpu</category>
      <category>engine</category>
      <category>mobile</category>
      <category>game</category>
    </item>
    <item>
      <title>Visual Scripting with JS&amp;NodeJS</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Thu, 18 Dec 2025 14:29:53 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/visual-scripting-with-jsnodejs-50p</link>
      <guid>https://dev.to/zlatnaspirala/visual-scripting-with-jsnodejs-50p</guid>
      <description>&lt;p&gt;YT: &lt;a href="https://www.youtube.com/watch?v=vT1zL5oNITY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=vT1zL5oNITY&lt;/a&gt;&lt;br&gt;
Source : &lt;a href="https://github.com/zlatnaspirala/matrix-engine-wgpu" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-wgpu&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FluxCodexVertex Web Editor 🚀 (since version 1.8.0)
&lt;/h2&gt;

&lt;p&gt;EditorX has &lt;strong&gt;two main parts&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt; (&lt;code&gt;./src/tools/editor&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt; (&lt;code&gt;./src/tools/editor/backend&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Before running anything&lt;/strong&gt;, install dependencies with &lt;code&gt;npm i&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in the &lt;strong&gt;root&lt;/strong&gt; folder
&lt;/li&gt;
&lt;li&gt;and also inside &lt;code&gt;./src/tools/editor/backend&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The backend is built using &lt;strong&gt;Node.js&lt;/strong&gt; 🟢&lt;/p&gt;




&lt;h2&gt;
  
  
  General Features 🧩
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Editor creates and manages files (Windows tested only)&lt;/li&gt;
&lt;li&gt;Scene container added&lt;/li&gt;
&lt;li&gt;SceneObject property container added&lt;/li&gt;
&lt;li&gt;Assets toolbar added (bottom panel)

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;GLB&lt;/strong&gt; or &lt;strong&gt;OBJ&lt;/strong&gt; files from the asset toolbox by selecting them&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Top menu for adding primitives (Cube / Sphere) with or without physics ⚙️&lt;/li&gt;

&lt;li&gt;Integrated Visual Scripting system 🧠&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Scripting – Implemented Features ✅
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;Math nodes&lt;/strong&gt;, &lt;strong&gt;events / custom methods&lt;/strong&gt;, &lt;strong&gt;variable popup&lt;/strong&gt;, &lt;strong&gt;SceneObject access&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Get SceneObject → set position → bind &lt;code&gt;onTargetReach&lt;/code&gt; events&lt;/li&gt;
&lt;li&gt;Custom func editor&lt;/li&gt;
&lt;li&gt;Run the graph ▶️&lt;/li&gt;
&lt;li&gt;Save graph

&lt;ul&gt;
&lt;li&gt;Currently saved to &lt;strong&gt;LocalStorage&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;For final builds, becomes a real &lt;strong&gt;JS object&lt;/strong&gt; injected into the app flow.[NOT DONE]
Now it is posible to hide editor on begin.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Export graph to &lt;strong&gt;JSON&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Import graph from &lt;strong&gt;JSON&lt;/strong&gt;
&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Important Notes
&lt;/h2&gt;

&lt;p&gt;Visual Scripting is only available when running the engine &lt;strong&gt;from source&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(not from &lt;code&gt;npm i matrix-engine-wgpu&lt;/code&gt;).  &lt;/p&gt;

&lt;p&gt;You must clone or download the engine source from the &lt;strong&gt;GitHub repository&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Instructions 📌
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run the editor with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run editorx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from the engine root directory.&lt;br&gt;
EditorX is an alias for FluxCodexVertex (needed three words to keep the name unique)&lt;br&gt;
Run the scene by pressing F6 or by clicking Run in the left panel&lt;br&gt;
If you delete all objects from the scene, you must refresh the page and add at least one object again&lt;br&gt;
Before importing a graph, delete all nodes from the FluxCodexVertex graph&lt;br&gt;
Saving is still based on LocalStorage&lt;br&gt;
After deleting everything, click Save to store an empty [] array&lt;br&gt;
All changes in graph must be saved manually/clicking for now 💾 (no autosave for graphs).&lt;/p&gt;

</description>
      <category>visualscripting</category>
      <category>online</category>
      <category>webgpu</category>
      <category>engine</category>
    </item>
    <item>
      <title>RPG in Javascript DeepWIP</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Mon, 27 Oct 2025 21:11:44 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/rpg-in-javascript-deepwip-39jk</link>
      <guid>https://dev.to/zlatnaspirala/rpg-in-javascript-deepwip-39jk</guid>
      <description>&lt;p&gt;RPG is tutorial example for matrix-engine-wgpu.&lt;/p&gt;

&lt;p&gt;Welcome to colaborate on github.com !&lt;/p&gt;

&lt;p&gt;webGPU engine open source : &lt;br&gt;
&lt;a href="https://github.com/zlatnaspirala/matrix-engine-wgpu" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-wgpu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live links: &lt;br&gt;
&lt;a href="https://maximumroulette.com/apps/webgpu/examples.html" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/webgpu/examples.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=_uu_EvxK8Vc&amp;amp;t=20s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=_uu_EvxK8Vc&amp;amp;t=20s&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=QFsR0u6x9qw" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=QFsR0u6x9qw&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=UHsRXQEd698" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=UHsRXQEd698&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5ihnrykug11elbrjul4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5ihnrykug11elbrjul4.png" alt="Select hero screen" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68eyqjowfovpo1670ej8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68eyqjowfovpo1670ej8.png" alt="RPG in JS webgpu" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>colaborate</category>
    </item>
    <item>
      <title>Rocket Crafting Platform- One source all platforms</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Tue, 27 May 2025 12:10:39 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/rocket-crafting-platform-one-source-all-platforms-1e4e</link>
      <guid>https://dev.to/zlatnaspirala/rocket-crafting-platform-one-source-all-platforms-1e4e</guid>
      <description>&lt;p&gt;Rocket Crafting Platform is separated on two main git projects, Rocket-Craft (Unreal Engine Projects) and RocketCraftingServer (Node.js project - account session).&lt;/p&gt;

&lt;p&gt;One source all platforms &lt;br&gt;
Project Slogan&lt;br&gt;
If you dont wanna to build HTML5 or dedicated servers than you no need UE4 from source. You need to build unreal engine with websocket net driver activated for HTML5 building [html5 websocket networking - Plugin]. On web page you can't use options HOST. On web platform client is just a client you can't host [open port and listen] but you can connect to other clients or dedicated server also communicate with HTTP/HTTPS protocol rocketCraftingServer [node.js]. &lt;/p&gt;

&lt;p&gt;Github repo link: Rocket Craft This is client part based on UE4 engine.&lt;/p&gt;

&lt;p&gt;Based on &lt;code&gt;Unreal Motion Graphics&lt;/code&gt; to create UI elements and ue4 3d graphics multiplatform implementation. Best solution for multiplatform developing choose in almost any aspect. &lt;/p&gt;

&lt;p&gt;Rocket-craft C++/Blueprints Features:&lt;br&gt;
Account registration, verification, login , user data and other func. Done in Node.js project name rocketCraftingServer. Used http/s protocol for communication.&lt;br&gt;
Handling JSON response/response with rocketCraftServer or any other.Used VAST plugin for handling JSON in blueprint.&lt;br&gt;
Handling active server list also add your external ip to server list if you wanna your own host - You need to open port on router page if you wanna be public visible. For LAN no need to do this.&lt;/p&gt;

&lt;p&gt;Nature Ue4 features:&lt;br&gt;
Host game with from client. Client can be used like server listener (this is not case only for web because it is not possible).&lt;br&gt;
Use dedicated server (i use it like master gameplay server with public access for &lt;code&gt;Brm&lt;/code&gt;, &lt;code&gt;Hange3d nightmare&lt;/code&gt;game project) Hosted on cent os 8.3 with node http server. Real time multiplayer games must have dedicated server to make instan and easy access to global main playground.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Unreal engine to create classic 2d context applications. Similar to the standard web application. Rocket is most powerfull cross platform tool i need to use it. 4.24.3 version is most interest checkpoint for UE. Last version with &lt;code&gt;only&lt;/code&gt; opengles 2.0 devices support (mobile). Also is version where we use new feature &lt;code&gt;exstension HTML5 build&lt;/code&gt;. Explanation: with opengles 2.0 (also opengles 3) we can still build our application for old android 5/6/7/8... os. In other way 4.24.3 is one of the last releases. Future upgrade will be easy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ue4 Editor build from source to get power of dedicated server build options.&lt;/p&gt;

&lt;p&gt;+------------------------------------------+&lt;br&gt;
 |                                          |&lt;br&gt;
 |   Build from source Unreal Engine        |&lt;br&gt;
 |   Current active and ultimate version    |&lt;br&gt;
 |   is 4.24.3 Read more from html5 ue4     |&lt;br&gt;
 |   exstension github repo readme files.   |&lt;br&gt;
 |                                          |&lt;br&gt;
 |                                          |&lt;br&gt;
 |        Ultimate multiplatform solution.  |&lt;br&gt;
 |       +-------------------------------+  |&lt;br&gt;
 |       |                               |  |&lt;br&gt;
 |       |   ONE SOURCE ALL PLATFORMS    |  |&lt;br&gt;
 |       |                               |  |&lt;br&gt;
 |       +-------------------------------+  |&lt;br&gt;
 |                                          |&lt;br&gt;
 |  UMG/2d Context 3d PhysX libwebSockets   |&lt;br&gt;
 |                                          |&lt;br&gt;
 +------------------------------------------+ &lt;br&gt;
Client part contain next projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Upgraded SurvivalGame Zombies Shooter multiplayer from Tom Looman&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BarbarianRoadMashines [primary work-in-progress] own work&lt;/li&gt;
&lt;li&gt;ShooterGame from Ue4 c++ template&lt;/li&gt;
&lt;li&gt;FullSpectrum is empty basic usage for rocketCraftinServer (Login/Register)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;SOURCE : &lt;a href="https://github.com/RocketCraftingServer/rocket-craft" rel="noopener noreferrer"&gt;https://github.com/RocketCraftingServer/rocket-craft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SERVER ACCOUNT SESSION PART&lt;br&gt;
Github repo link Rocket Craft Server. Basic account session staff based on node.js and MongoDB. This repo is private you will need to join the team and participate to get your copy: &lt;a href="https://github.com/orgs/RocketCraftingServer/teams/rocketcraftingteam" rel="noopener noreferrer"&gt;https://github.com/orgs/RocketCraftingServer/teams/rocketcraftingteam&lt;/a&gt; Contact me for invitation. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Barbarian Road Mashines
This is race game with zombies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[ beta version downloads / proof of concept ]:&lt;/p&gt;

&lt;p&gt;HTML5 &lt;br&gt;
&lt;a href="http://brm.maximumroulette.com/" rel="noopener noreferrer"&gt;http://brm.maximumroulette.com/&lt;/a&gt;&lt;br&gt;
Windows 64 &lt;br&gt;
Windows 32&lt;br&gt;
Windows dedicated server&lt;br&gt;
 Mac OS No build&lt;br&gt;
Linux Dedicated server&lt;br&gt;
Linux&lt;br&gt;
LinuxAArch64&lt;br&gt;
Android No build&lt;br&gt;
iOS No build&lt;br&gt;
SonyPS No build&lt;br&gt;
XBox No build&lt;br&gt;
BarbarianRoadMashines Beta Testing Video&lt;/p&gt;

&lt;p&gt;HANG3D NIGHTMARE [Shooter]&lt;br&gt;
In 'Hang3d Nightmare' fot web platform use only INSTANT PLAY options. &lt;/p&gt;

&lt;p&gt;Multiplayer is currently supported by maximumroulette.com dedicated server [linux cent os 8.3] Server builded on windows host mashine using &lt;code&gt;v15_clang-8.0.1-centos7&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;No alt text provided for this image&lt;br&gt;
Use INSTANT PLAY tab in main menu if you using web (browser) version.&lt;/p&gt;

&lt;p&gt;No alt text provided for this image&lt;/p&gt;

&lt;p&gt;Downloads : &lt;/p&gt;

&lt;p&gt;opengles2&lt;br&gt;
&lt;a href="http://maximumroulette.com/apps/shooter/hang3d-nightmare.html" rel="noopener noreferrer"&gt;Live HTML5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;opengles3&lt;br&gt;
&lt;a href="https://maximumroulette.com/apps/hang3d/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/hang3d/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows 64bit&lt;br&gt;
Windows 32bit&lt;br&gt;
Windows dedicated&lt;br&gt;
Linux dedicated&lt;br&gt;
MACOS&lt;br&gt;
iOS&lt;br&gt;
ANDROID&lt;/p&gt;

&lt;p&gt;Chrome Test first build [beta ver] video. &lt;/p&gt;

&lt;p&gt;Use profiler fot tex LODS and setup max value 512 or 256. To make smaller pack of data.&lt;/p&gt;

&lt;p&gt;Shoot the zombie (Survival) &lt;br&gt;
Realistic rendering - Ue4 template &lt;/p&gt;

&lt;p&gt;No alt text provided for this image&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;build target HTML5 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;emscripten 1.39.0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Max tex lod size 512 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;App size 197mb&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Link : &lt;a href="https://maximumroulette.com/apps/realistic-rendering/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/realistic-rendering/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FUTURE WAS HERE ALL THE TIME&lt;/p&gt;

&lt;p&gt;It gives us power of rocket to build and pack app for Windows, MacOs, Linux, Android, iOS, xBox, Sony Playstation, web/html5 etc...&lt;/p&gt;

&lt;p&gt;One source all platforms &lt;br&gt;
Project Slogan&lt;br&gt;
Help for c++ template projects&lt;br&gt;
This is only for ue from source case (when you wanna dedicated server builds) in other way just use &lt;code&gt;build&lt;/code&gt; project, for full rebuild use &lt;code&gt;rebuild&lt;/code&gt; project.&lt;/p&gt;

&lt;p&gt;The option you are referring to (Build -&amp;gt; Project Only -&amp;gt; Clean Only "ProjectName") is a Visual Studio option, not one that is exclusive to Unreal Engine 4. What actually happens when a Project Only Clean process is begun, is that Visual Studio not only cleans the Project, but it also checks to see if it is able to clean anything that the Project depends on. Since you are using a version of the Engine that is built from source code, Visual Studio includes that dependency in the Clean process, which ends up requiring a full build of the Engine. The same occurs if you attempt to rebuild the project only. If you wish to be able to perform a clean at only the project level, you would need to navigate to where your project is located in a Windows Explorer window. In the root project folder, delete the Binaries, Build, DerivedDataCache, and Intermediate folders. Right-click on the project's .uproject file and select the Generate Visual Studio project files option (this will recreate the Intermediate folder). Open the project solution in Visual Studio and Build the project (this will recreate the Binaries and Build folders). When the build completes in Visual Studio, double-click the project's .uproject file to open it in the Editor(this will recreate the DerivedDataCache folder).You should now have a "Clean" project without needing to rebuild the Engine. Source: &lt;a href="https://answers.unrealengine.com/questions/100921/view.html?sort=oldest" rel="noopener noreferrer"&gt;https://answers.unrealengine.com/questions/100921/view.html?sort=oldest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multiplayer dedicated server not active !&lt;br&gt;
If you wanna support me for new VPS and domain you will be project sponsor&lt;br&gt;
paypal &lt;a href="mailto:zlatnaspirala@gmail.com"&gt;zlatnaspirala@gmail.com&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Matrix-roulette - Physics + Server game regime</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Wed, 23 Apr 2025 12:57:51 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/matrix-roulette-physics-server-game-regime-2leh</link>
      <guid>https://dev.to/zlatnaspirala/matrix-roulette-physics-server-game-regime-2leh</guid>
      <description>&lt;h1&gt;
  
  
  matrix-roulette 1.0.0
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Prerequirement
&lt;/h3&gt;

&lt;p&gt;You need Node.js and npm to be instaled.&lt;/p&gt;

&lt;pre&gt;npm install -g browserify
&lt;/pre&gt;

&lt;h3&gt;
  
  
  Install frontend deps in root foledr with:
&lt;/h3&gt;

&lt;pre&gt;npm i
&lt;/pre&gt;

&lt;h3&gt;
  
  
  Install backend deps in folder &lt;code&gt;./server&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;npm i
&lt;/pre&gt;

&lt;h3&gt;
  
  
  Watch/build frontend (from root folder) with:
&lt;/h3&gt;

&lt;pre&gt;  npm run roulette
&lt;/pre&gt;

&lt;h3&gt;
  
  
  Build your Application (from root folder) script bundle with:
&lt;/h3&gt;

&lt;pre&gt;  npm run build.roulette
&lt;/pre&gt;

&lt;p&gt;You need to run any web server.&lt;br&gt;
And navigate to &lt;code&gt;/projects/matrix-roulette/?server=manual&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Matrix Roulette - Server regime
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;projects\matrix-roulette&lt;/code&gt; Used Server Events tech.&lt;/p&gt;

&lt;p&gt;New feature is ServerEvent tech.&lt;/p&gt;

&lt;p&gt;Run matrix-roulette-server on localhost with:&lt;/p&gt;

&lt;pre&gt;npm run dev
&lt;/pre&gt;

&lt;p&gt;Run matrix-roulette-server on public server with:&lt;/p&gt;

&lt;pre&gt;npm start
&lt;/pre&gt;

&lt;p&gt;For production you need to change this part and put your own SSL domain name:&lt;br&gt;
I use setup frendly with letsencrypt services.&lt;br&gt;
Change path whatever be...&lt;/p&gt;

&lt;p&gt;If you wanna server regime navigate to:&lt;br&gt;
&lt;code&gt;/projects/matrix-roulette/?server=true&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Setup SSL for server part
&lt;/h3&gt;

&lt;pre&gt;if(URL_ARG.indexOf("localhost") !== -1) {
    console.log('Dev regime is active...');
    options = {
        key: fs.readFileSync(__dirname + "/self-cert/privatekey.pem"),
        cert: fs.readFileSync(__dirname + "/self-cert/certificate.pem")
    };
} else {
    options = {
        key: fs.readFileSync("/etc/letsencrypt/live/[YOR_OWN_DOMAIN_ENTER_HERE]/privkey.pem"),
        cert: fs.readFileSync("/etc/letsencrypt/live/[YOR_OWN_DOMAIN_ENTER_HERE]/fullchain.pem")
    };
}
&lt;/pre&gt;

&lt;p&gt;File &lt;code&gt;roulette\server\matrix-roulette-server.js&lt;/code&gt; is example for node.js webserver running stanalone with&lt;br&gt;
roulette feature. If you already have your web server then you no need this file just import&lt;br&gt;
&lt;code&gt;roulette\server\core.js&lt;/code&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  For node.js looks like:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;facts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./core.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;hostingHTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/matrix-roulette-status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;eventsHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keep-alive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`data: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;facts&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newClient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Connection closed`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matrixRouletteCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;hostingHTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/matrix-roulette&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventsHandler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Look like:&lt;/p&gt;

&lt;pre&gt;const events = new EventSource("https://maximumroulette.com/matrix-roulette");
events.onmessage = event =&amp;gt; {
  console.log("MatrixRoulette:", event);
};
&lt;/pre&gt;

&lt;p&gt;If you see in browser debuger logs msg: &lt;/p&gt;

&lt;pre&gt; EventSource failed loading: GET "https://localhost:8080/matrix-roulette".
&lt;/pre&gt;

&lt;p&gt;It means you dont have runned server part.&lt;/p&gt;
&lt;h4&gt;
  
  
  Url parameters:
&lt;/h4&gt;

&lt;pre&gt; +-----------------------------------------------------------------------------------+
 |-----------------------------------------------------------------------------------+
 ||       URLParameter          value          Description                           |
 +-----------------------------------------------------------------------------------+
 |                                                                                   |
 |        ?server=              manual         Server is used for video chat etc not |
 |                                             gameplay results.Wheel view is called |
 |                                                              on SPIN procedure.   |
 |        ?server=              true           Server dictate results but no wheel   |
 |                                                                                   |
 |                                                                                   |
 |        &amp;amp;sounds=              true/false     Sounds are active only if url param   |
 |                                             is true.                              |
 |                                                                                   |
 |        &amp;amp;cameraSpeed=         Number         Best range values from 0.5 to 1       |
 |                                                                                   |
 |                                                                                   |
 +-----------------------------------------------------------------------------------+

&lt;/pre&gt;

&lt;p&gt;Dev links looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://localhost:8080/?server=true" rel="noopener noreferrer"&gt;https://localhost:8080/?server=true&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://localhost:8080/?server=manual" rel="noopener noreferrer"&gt;https://localhost:8080/?server=manual&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Notes
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Used cannon.js integration for matrix-engine.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Video chat support (bonus feature [wip]):
&lt;/h3&gt;

&lt;p&gt;(You need to run your own openvide/kurento server)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;matrixEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activateNet2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;sessionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;matrix-roulette&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;240x160&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Table bet view and  Wheel view
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6hr0gx4qzit25729vdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6hr0gx4qzit25729vdg.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0q2gsb3agj5r2rxbtwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0q2gsb3agj5r2rxbtwx.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo from this repo:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-roulette/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-roulette/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zlatnaspirala/matrix-engine-starter" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-starter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Engine source link:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zlatnaspirala/matrix-engine" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.wildtextures.com" rel="noopener noreferrer"&gt;https://www.wildtextures.com&lt;/a&gt;
&lt;a href="https://www.freesoundtrackmusic.com/guest/demolib" rel="noopener noreferrer"&gt;https://www.freesoundtrackmusic.com/guest/demolib&lt;/a&gt;
CenterRoll downloaded from &lt;a href="http://www.blendswap.com/blends/view/72520" rel="noopener noreferrer"&gt;http://www.blendswap.com/blends/view/72520&lt;/a&gt;
and taken only one part.
In readme.md you have licence just leave it to make legal use.
For example copy intro same folder like index.html file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Join chat on slack
&lt;/h3&gt;

&lt;p&gt;(GamePlay platform Rock)[&lt;a href="https://join.slack.com/t/gameplay-rock/shared_invite/zt-ffcgl80x-CYu4s%7EYC0bD9Od9_bkqmzw" rel="noopener noreferrer"&gt;https://join.slack.com/t/gameplay-rock/shared_invite/zt-ffcgl80x-CYu4s~YC0bD9Od9_bkqmzw&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>roulette</category>
      <category>javascript</category>
      <category>matrixengine</category>
      <category>webgl</category>
    </item>
    <item>
      <title>Matrix-engine 2.x.x</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Fri, 06 Dec 2024 21:49:18 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/matrix-engine-2xx-5ff0</link>
      <guid>https://dev.to/zlatnaspirala/matrix-engine-2xx-5ff0</guid>
      <description>&lt;p&gt;Detect groups from 3d obj file format.Then add collider box &lt;br&gt;
on every mesh with name sufix or prefix  Cube.COLLIDER.1.&lt;br&gt;
This is update for matrix-engine obj loader.&lt;/p&gt;

&lt;p&gt;See YT video:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=_ISsjt0GXww&amp;amp;t=808s" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=_ISsjt0GXww&amp;amp;t=808s&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Project source: *&lt;/em&gt;&lt;br&gt;
&lt;a href="https://github.com/zlatnaspirala/matrix-engine-starter" rel="noopener noreferrer"&gt;https://github.com/zlatnaspirala/matrix-engine-starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zqce3vmoov553ba6qu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zqce3vmoov553ba6qu8.png" alt="FPS Template with colliders map from blender" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrwgs8mbwaw7kfxehrt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrwgs8mbwaw7kfxehrt1.png" alt="Matrix Slot optimised for mobile devices" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update Details :
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2.1.6] Added map creator from starter project.

[2.1.1] Just added example how to load maps and detect groups vertices.

[2.1.0] Added MapCreator web tools
 New export for npm pack `meMapLoader`
 Usage:
Automatic load on refresh me app. MapCreator make saves on every new field.
You need just to refresh page.


    if (localStorage.getItem('map') != null) {
        var t = localStorage.getItem('map');
        t = JSON.parse(t)
        meMapLoader.load(t, physics);
    } else {
        meMapLoader.load(map, physics);
    }



If you wanna just always load map from disk/file then use:


import {map} from "../maps/map2";

...

meMapLoader.load(map, physics);



To make map goto `public\tools\map-creator.html`


[2.1.4] draObj DRAW



object.instancedDraws.overrideDrawArraysInstance(object);

objObject.instancedDraws = {
  numberOfInstance: 10,
  array_of_local_offset: [0, 0, 0],
  overrideDrawArraysInstance: function (object_) {}
};



[2.1.3] Prevent error [render file]



else if(local.physics.currentBody.shapeOrientations.length &amp;gt; 1) {
                    // Check
                    if (local.subObjs) for(var x = 0;x &amp;lt; local.subObjs.length;x++) {



[2.1.2]You can scale mesh general with:


App.scene.armor.mesh.setScale(2);



Or by axis:



App.scene.armor.mesh.setScale({x: 1, y: 2, z: 2});



[2.1.1] testTrimesh added , visual OK , physics need more updated.
Cannonjs collision not work for this type of custom geo object...



world.Add('generatorLightTex', 1, 'floorAngle', tex, {
  radius: 1,
  custom_type: 'testTrimesh',
  custom_geometry: new CANNON.Trimesh(vertices, indices)
});



[2.1.0] Much better physics for cube
Line:



var AXIS = vec3.fromValues(-parseFloat(object.rotation.axisSystem[0].x.toFixed(2)), parseFloat(object.rotation.axisSystem[0].z.toFixed(2)), parseFloat(object.rotation.axisSystem[0].y.toFixed(2)));



[2.0.38] Full custom geometry inject cannonjs shape object for
for CANNON.ConvexPolyhedron.
Example of usage:



world.Add('generatorLightTex', 1, 'outsideBox2', tex, {
  radius: 1,
  custom_type: 'testConvex',
  custom_geometry: createTetra()
});



[2.0.34] New App flag: App.printDevicesInfo: false

[2.0.31] Simplify `SET_STREAM` for ACCESS CAMERA

[2.0.30]
For FirstPersonController added move in left or right by side...
UPDATE IN setCamera func:


// For FirstPersonController
camera.setCamera = function (object) {
  if (keyboardPress.getKeyStatus(65) || App.camera.leftEdge == true) {
    /* A */
    camera.yawRate = App.camera.yawRate;
    if (App.camera.leftEdge == true) {
      camera.yawRate = App.camera.yawRateOnEdge;
    }
  } else if (keyboardPress.getKeyStatus(68) || App.camera.rightEdge == true) {
    /* D */
    camera.yawRate = -App.camera.yawRate;
    if (App.camera.rightEdge == true) {
      camera.yawRate = -App.camera.yawRateOnEdge;
    }
  } else if (keyboardPress.getKeyStatus(32)) {
    /* Right Key or SPACE */
    if (this.virtualJumpActive != true) {
      this.virtualJumpActive = true;
    }
  }

  if (keyboardPress.getKeyStatus(37)) {
    /* Left Key  || App.camera.leftEdge == true*/
    camera.moveLeft = true;
    camera.speed = App.camera.speedAmp;
  } else if (keyboardPress.getKeyStatus(39)) {
    /* Right Key || App.camera.rightEdge == true */
    camera.moveRight = true;
    camera.speed = App.camera.speedAmp;
  } else if (keyboardPress.getKeyStatus(38) || keyboardPress.getKeyStatus(87)) {
    /* Up Key or W */
    camera.speed = App.camera.speedAmp;
  } else if (keyboardPress.getKeyStatus(40) || keyboardPress.getKeyStatus(83)) {
    /* Down Key or S */
    camera.speed = -App.camera.speedAmp;
  } else {
    // if(camera.preventSpeedZero == false) camera.speed = 0;
  }

  /* Calculate yaw, pitch and roll(x,y,z) */
  if (camera.speed != 0 &amp;amp;&amp;amp; camera.moveLeft == false &amp;amp;&amp;amp; camera.moveRight == false) {
    camera.xPos -= Math.sin(degToRad(camera.yaw)) * camera.speed;
    if (camera.fly == true) {
      // Fly regime
      camera.yPos += Math.sin(degToRad(camera.pitch)) * camera.speed;
    } else {
      // usually for fpshooter regime
      // camera.yPos = this.virtualJumpY;
      // camera.yPos = 0;
      // leave it zero by default lets dirigent from top
    }
    camera.zPos -= Math.cos(degToRad(camera.yaw)) * camera.speed;
  } else if (camera.moveLeft == true) {
    // by side move left
    camera.xPos -= Math.sin(degToRad(camera.yaw + 90)) * camera.speed;
    camera.zPos -= Math.cos(degToRad(camera.yaw + 90)) * camera.speed;
  } else if (camera.moveRight == true) {
    // by side move rigth
    camera.xPos -= Math.sin(degToRad(camera.yaw - 90)) * camera.speed;
    camera.zPos -= Math.cos(degToRad(camera.yaw - 90)) * camera.speed;
  }

  camera.yaw += camera.yawRate * camera.yawAmp;
  camera.pitch += camera.pitchRate * camera.pitchAmp;

  mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(-camera.pitch), [1, 0, 0]);
  mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(-camera.yaw), [0, 1, 0]);
  mat4.translate(object.mvMatrix, object.mvMatrix, [-camera.xPos, -camera.yPos, -camera.zPos]);

  camera.yawRate = 0;
  camera.pitchRate = 0;
  // update
  camera.moveLeft = false;
  camera.moveRight = false;
  if (camera.preventSpeedZero == false) camera.speed = 0;
};


[2.0.27] Added for CustomGeometry object entity:


customObject.net = {
  enabled: false
};


[2.0.26] FIX CHECK NET ACTIVE FLAG FOR SCALE PROCEDURE

[2.0.25] FIX FOR MOBILE RENDER MATERIAL/ TEXTURE - Bug with white surface


// world.disableUnusedAttr(world.GL.gl, localLooper);
world.disableUnusedAttr(world.GL.gl, 4);


[2.0.24] New prop in App.camera (manifest)

    `App.camera.yawRateOnEdge`


camera.setCamera = function(object) {
    if(keyboardPress.getKeyStatus(37) || keyboardPress.getKeyStatus(65) || App.camera.leftEdge == true) {
        /* Left Key  or A */
        camera.yawRate = App.camera.yawRate;
        if(App.camera.leftEdge == true) {
            camera.yawRate = App.camera.yawRateOnEdge;
        }
    } else if(keyboardPress.getKeyStatus(39) || keyboardPress.getKeyStatus(68) || App.camera.rightEdge == true) {
        /* Right Key or D */
        camera.yawRate = -App.camera.yawRate;
        if(App.camera.rightEdge == true) {
            camera.yawRate = -App.camera.yawRateOnEdge;
        }
    }


[2.0.23] New line in EVENTS About WASD FPController
Reason - adaptation for mobile FPController
`   if (camera.preventSpeedZero == false) camera.speed = 0;`

js
/* Up Key or W */
if (keyboardPress.getKeyStatus(38) || keyboardPress.getKeyStatus(87)) {
  camera.speed = App.camera.speedAmp;
} else if (keyboardPress.getKeyStatus(40) || keyboardPress.getKeyStatus(83)) {
  /* Down Key or S */
  camera.speed = -App.camera.speedAmp;
} else {
  if (camera.preventSpeedZero == false) camera.speed = 0;
}


[2.0.17 version Vampir]
Objective

- Deplace old networking and put kurento/OV web client code.
- Mobile device ready
- GUI Editor (win) basic version ready

[2.0.17] New event from core net updater.
`dispatchEvent('network-data', {detail: e.data})`
For better customisation.

js
update(e) {
            e.data = JSON.parse(e.data);
            dispatchEvent('network-data', {detail: e.data})
            // console.log('INFO UPDATE', e);
            if(e.data.netPos) {
                if(App.scene[e.data.netObjId]) {
                    if(e.data.netPos.x) App.scene[e.data.netObjId].position.SetX(e.data.netPos.x, 'noemit');
                    if(e.data.netPos.y) App.scene[e.data.netObjId].position.SetY(e.data.netPos.y, 'noemit');
                    if(e.data.netPos.z) App.scene[e.data.netObjId].position.SetZ(e.data.netPos.z, 'noemit');
                }
            } else if(e.data.netRot) {


[2.0.16] Added to the Base Class Position `xNetOffset yNetOffset zNetOffset`
Nice for calibration.
[2.0.14] For obj sequency animation `objObject.scaleAll`



**New updates for Matrix-Roulette &amp;amp; hang3d FPS Basic template:**

https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-slot/

https://maximumroulette.com/apps/matrix-engine-starter/projects/hang3d/


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;New updates for Matrix-Roulette &amp;amp; hang3d FPS Basic template:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-slot/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-slot/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com/apps/matrix-engine-starter/projects/hang3d/" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/matrix-engine-starter/projects/hang3d/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for any support , &lt;br&gt;
Welcome for collaboration.&lt;/p&gt;

</description>
      <category>matrixengine</category>
      <category>javascript</category>
      <category>webgl</category>
      <category>webrtc</category>
    </item>
    <item>
      <title>Magic Three Project</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Fri, 13 Sep 2024 11:26:21 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/magic-three-project-1p7n</link>
      <guid>https://dev.to/zlatnaspirala/magic-three-project-1p7n</guid>
      <description>&lt;h2&gt;
  
  
  MagicThree
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com/apps/magic/public/module.html" rel="noopener noreferrer"&gt;Template/Demo FPS SHOOTER HANG3d reborn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using power of Three.js, ammo.js. MagicThree is nice class sorted top level of threejs and ammo.js lib. Magic-three use the new version threejs 149. [JS type of script module variant with last version of three.module.js]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extreme interest facts:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No spending times on build, magic-three use type module in browser.&lt;br&gt;
Using themes without scss - also no build.&lt;br&gt;
Combination Three.js vs ammo.js is last physics solution from three.js project.&lt;br&gt;
Using webRTC for networking/multiplayer brings video chat/stream in same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Magic-Three is First Person Oriented but can be used for any other case of app flow.&lt;/p&gt;

&lt;p&gt;No build needed, just copy/paste for both dev and prod mode.It is the module type of script. Nice fit with npm modules also works direct in browser.&lt;br&gt;
Custom magic Map loader. All 3d objects comes from map.&lt;br&gt;
No package.json [if this repo become npm package then will be back] In folder ./backend we have package.json to import deps (npm i) for server part. Run in folder ./backend cmd: npm i and npm run magic for host and broadcaster.&lt;br&gt;
Must be fully PWA [cache, server compression, image format webp etc...]&lt;br&gt;
MultiLang support [async load JSON MultiLang file avoid loading all multiLangs]&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Networking *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;based on webRtc multiRTC3 library. Signaling server, video chat or stream to texture.&lt;br&gt;
Basic example: FPS Player controller [bullet , collision]&lt;br&gt;
Frontend -&amp;gt; Three.js, Ammo.js&lt;br&gt;
Backend  -&amp;gt; Node.js, MultiRTC3&lt;br&gt;
Main gameplay template FPShoter: Hang3d Reborn&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Application.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./config.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;myGamePlayMagicMap&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./public/assets/maps/free-for-all.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myGamePlayMagicMap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Client Config&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fov&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;near&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;far&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YXZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;sky&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0xbfd1e5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;floorWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;floorHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;gravityConstant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;17.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;directionLight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;ambientLight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(250,250,250)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;meshShadows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;castShadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;receiveShadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;computeVertexNormals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;blockingVolumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;playerController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FPS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// FPS | orbit&lt;/span&gt;
    &lt;span class="na"&gt;movementType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;velocity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// velocity | kinematic&lt;/span&gt;
    &lt;span class="na"&gt;cameraInitPosition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;movementSpeed&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;jump&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;jumpLimitInterval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;physicsBody&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;bullet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;bulletLiveTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;networking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;broadcasterPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;broadcasterInit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// domain: "maximumroulette.com",&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;networkDeepLogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * masterServerKey is channel access id used to connect
     * endpoint p2p. Multimedia server channel/multiRTC3 used.
     */&lt;/span&gt;
    &lt;span class="na"&gt;masterServerKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;magic.three.main.channel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;runBroadcasterOnInt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;broadcasterPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 9010,&lt;/span&gt;
    &lt;span class="na"&gt;broadcastAutoConnect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;broadcasterSessionDefaults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sessionAudio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sessionVideo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sessionData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;enableFileSharing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;stunList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stun:stun.l.google.com:19302&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stun:stun1.l.google.com:19302&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stun:stun.l.google.com:19302?transport=udp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nf"&gt;getBroadcastSockRoute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getProtocolFromAddressBar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;getDomain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;broadcasterPort&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Blocking Volumes implemented for map - map.objMtlsArray :  Nice for walls and env staff. Forced simple cube physics body with mass = 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;br&gt;
Frontend done in script type "module" ant it's so powerfull. No build time lost and you can use direct import/export syntax.&lt;/p&gt;

&lt;p&gt;List of top level *&lt;em&gt;CustomEvents *&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;"config.map.blockingVolumes.visible" - if QueryString.dev == "true" (URL param ?dev=true)&lt;br&gt;
"onMyDamage"&lt;br&gt;
"onDie"&lt;br&gt;
"onFire"&lt;br&gt;
"hide-blocker"&lt;br&gt;
"multi-lang-ready"&lt;br&gt;
"addToOnlyIntersects"&lt;br&gt;
Explanation in next update...&lt;/p&gt;

&lt;p&gt;Initially video stream is deactivated. &lt;br&gt;
Manage this from config :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  broadcasterSessionDefaults: {
     sessionAudio: false,     // IMPORTANT
     sessionVideo: false,     // IMPORTANT
     sessionData: true,       // IMPORTANT
     enableFileSharing: true,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Backend part based on multiRTC3.&lt;br&gt;
For now only signaling pricipe is implemented. If you wanna start host server and broadcaster[webRtc] then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd backend
npm i
npm run magic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup in backend/magic-three.server.js your own domain: If you put "*" in public server someone can use your web app cross domain. This will be automated in future.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// res.setHeader('Access-Control-Allow-Origin', '*');
// res.setHeader('Access-Control-Allow-Origin', 'https://localhost:9001');
res.setHeader('Access-Control-Allow-Origin', 'https://maximumroulette:9001');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I force default browser port 443! To make all works fine (CORS problems). For localhost cert also better https. For public server you need classic ssl setup.&lt;/p&gt;

&lt;p&gt;Navigate (most simple way to fix localhost cert problem is to click advanced -&amp;gt; Proceed to localhost (unsafe)) &lt;a href="https://localhost/public/module.html" rel="noopener noreferrer"&gt;https://localhost/public/module.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If still networking not work then goto: &lt;a href="https://localhost:9001/" rel="noopener noreferrer"&gt;https://localhost:9001/&lt;/a&gt; click advanced -&amp;gt; Proceed to localhost (unsafe)&lt;/p&gt;

&lt;p&gt;Finally when you see html text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;********************************************************** 
* MatrixNet         version: 0.2.0                       * 
* Type of network - BROADCASTER                          * 
* Source: https://github.com/zlatnaspirala/matrix-engine * 
**********************************************************
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server is allowed for localhost.&lt;/p&gt;

&lt;p&gt;After all goto &lt;a href="https://localhost/public/module.html" rel="noopener noreferrer"&gt;https://localhost/public/module.html&lt;/a&gt; Must work now. You can easy manage paths. Default is https protocol and also recommended in multiplayer mode.&lt;/p&gt;

&lt;p&gt;Dev stage&lt;br&gt;
Easy running also on VPS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com/apps/magic/public/module.html" rel="noopener noreferrer"&gt;https://maximumroulette.com/apps/magic/public/module.html&lt;/a&gt;&lt;br&gt;
Features&lt;br&gt;
Dynamic Cache/Worker, add to home screen. [pwa]✅&lt;br&gt;
Graphics/Physics scene ready.✅&lt;br&gt;
Add 3d object loaders [fbx, collada].✅&lt;br&gt;
Script compression bash script.✅&lt;br&gt;
Basic FPS controller✅&lt;br&gt;
Adding map pack principle.✅&lt;br&gt;
Net Players.✅&lt;br&gt;
Tested on android12 devices.✅&lt;br&gt;
Real Day time - sky(shaders) done + wip envelop shaders adaptaion lights.⏳&lt;br&gt;
Add account options REST API [rocketCraftingServer]. singin , leaderboard. Only client part no need backend i already have running rcs on maximumroulette.com. ⏳&lt;br&gt;
Net Shared objects +.⏳&lt;br&gt;
Neutral enemy [bots] +.⏳&lt;br&gt;
Map [] ⏳&lt;br&gt;
Working example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let map = {
  breakable: [
    {
      name: "myBreakAbleBox1",
      mass: 100,
      scale: {x: 2, y: 5, z: 2},
      pos: {x: 3, y: 1, z: 1},
      quat: [0, 0, 0, 1],
      matFlag: 'Black' // new
    }
  ],
  boxs: [
    {
      name: "myMidBox1",
      net: true,
      mass: 10,
      scale: {x: 5, y: 5, z: 5},
      pos: {x: 0, y: 1, z: 20},
      quat: [0, 0, 0, 1],
      matFlag: 'Bronze'
    }
  ],
  tubes: [
    {
      name: "myTube1",
      mass: 1000,
      scale: [5, 5, 20, 32],
      pos: {x: -20, y: 1, z: -80},
      quat: [0, 0, 0, 1]
    },
    {
      name: "myTube2",
      mass: 1000,
      scale: [5, 5, 20, 32],
      pos: {x: 20, y: 1, z: -80},
      quat: [0, 0, 0, 1]
    }
  ],
  torus: [
    {
      name: "myTorus1",
      mass: 1000,
      scale: [10, 3, 16, 100],
      pos: {x: 30, y: 1, z: 1},
      quat: [0, 0, 0, 1]
    }
  ],
  pointLights: [
    {
      name: 'l1',
      color: 0xff0040,
      radius: 2,
      intensity: 150,
      pos: {x: 30, y: 12, z: 10},
      helper: true
    },
    {
      name: 'l2',
      color: 0xeeee40,
      radius: 2,
      intensity: 510,
      pos: {x: -30, y: 12, z: 10},
      helper: true
    }
  ],
  objMtls: [
    {
      path: 'assets/objects/env/wall1.obj',
      name: 'myWall_1',
      pos: {x:-100, y:-0.5, z:-42}
    }
  ],
  objMtlsArray: [
    {
      path: 'assets/objects/env/wall1.obj',
      name: 'myWall',
      instances: [
        {pos: {x: -100, y: -0.5, z: -62}},
        {
          pos: {x: 52.8, y: -0.5, z: 86.5},
          rot: {x: 0, y: 90, z: 0}
        }
      ]
    }
  ]
};

export default map;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;More info about PWA *&lt;/em&gt;⏳&lt;/p&gt;

&lt;p&gt;I have performance stable at ~90% value. I load extra fbx animation 22Mb to test little more better. Image formats like WebP and AVIF often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. I use freeware GIMP he had a webp format support for exports.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Lighthouse screenshot: *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No need for PWA at dev/localhost work. In final time you can use .prod.js compressed files to make full optimised app with better preformance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MultiLang [strings]&lt;/strong&gt;&lt;br&gt;
Only on startup for now:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;addEventListener('multi-lang-ready', () =&amp;gt; {
  byId('header.title').innerHTML = t('title');
  byId('player.munition.label').innerHTML = t('munition');
  ...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;*&lt;em&gt;Networking [WEBRTC/IOSOCKET] *&lt;/em&gt;💫&lt;/p&gt;

&lt;p&gt;I use classic broadcester from matrix-engine-server/visual ts [multiRTC3]&lt;br&gt;
Every player send own net.connection.userid.&lt;br&gt;
Type of gameObject boxs map loader have support for net emit. ⏳&lt;br&gt;
Explanation of FPS used concept&lt;br&gt;
Local Player have no any visual objs , only main three.js camera follow player position and look direction.&lt;br&gt;
Net Player [remote player] have visualization with FBX animation. Net rotated only for Y axis for now.&lt;br&gt;
Local Player have physics body ball who is moved from physics world on that way we got all collision problem fixed.&lt;br&gt;
Net Player have no physics body also no any collision objs i use raycaster from three.js in net player case On that way i got optimised and precise situation with netplayer handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credits &amp;amp;&amp;amp; Licence&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://threejs.org/" rel="noopener noreferrer"&gt;https://threejs.org/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/kripken/ammo.js/" rel="noopener noreferrer"&gt;https://github.com/kripken/ammo.js/&lt;/a&gt;&lt;br&gt;
In Assets i use great &lt;a href="https://mixamo.com/" rel="noopener noreferrer"&gt;https://mixamo.com/&lt;/a&gt;&lt;br&gt;
Mobile controller used from &lt;a href="https://github.com/KEY4d-LAB/crypto-art-town" rel="noopener noreferrer"&gt;https://github.com/KEY4d-LAB/crypto-art-town&lt;/a&gt;&lt;br&gt;
Networking based on &lt;a href="https://github.com/muaz-khan/RTCMultiConnection" rel="noopener noreferrer"&gt;https://github.com/muaz-khan/RTCMultiConnection&lt;/a&gt;&lt;br&gt;
Font wargames used from &lt;a href="https://www.dafont.com/wargames.font" rel="noopener noreferrer"&gt;https://www.dafont.com/wargames.font&lt;/a&gt;&lt;br&gt;
Audios , Great staff at &lt;a href="https://gamesounds.xyz/?dir=OpenBundle" rel="noopener noreferrer"&gt;https://gamesounds.xyz/?dir=OpenBundle&lt;/a&gt; &lt;a href="https://gamesounds.xyz/OpenBundle/LICENSE.txt" rel="noopener noreferrer"&gt;https://gamesounds.xyz/OpenBundle/LICENSE.txt&lt;/a&gt;&lt;br&gt;
More&lt;br&gt;
Most effect dimanic thermes with native css and control from javascript&lt;br&gt;
Using css vars from vars.css.&lt;br&gt;
**&lt;br&gt;
Script:**&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {setCssVar} from "./utility.js"

export class MagicTheme {

    Light() {
        console.log('THEME LIGHT SET')
        setCssVar("--bg", "#6b6b6b33")
        setCssVar("--text", "hsl(1, 20%, 100%)")
        setCssVar("--text2", "rgb(0, 0, 0)")
        setCssVar("--err", "orangered")
        setCssVar("--bgBlocker", "rgba(150, 150, 150, 0.9)")
        setCssVar("--bgTransparent1", "rgba(0, 0, 0, 0.1)")
        setCssVar("--LG1", "linear-gradient(87deg,#ff6f00,#b5830f,#df494b,#fff,#fff,#e90b0f)")
        setCssVar("--mainFont", "Accuratist")
    }

    Dark() {
        setCssVar("--bg", "#0d2d4e")
        setCssVar("--text", "hsl(0, 0%, 100%)")
        setCssVar("--text2", "rgb(255, 253, 192)")
        setCssVar("--err", "red")
        setCssVar("--bgBlocker", "rgba(10, 10, 10, 0.9)")
        setCssVar("--bgTransparent1", "rgba(0, 0, 0, 0.1)")
        setCssVar("--LG1", "linear-gradient(87deg,#00b3ff,#510fb5,#49cbdf,#000000,#000000,#1d0be9)")
        setCssVar("--mainFont", "stormfaze")
    }

    Green() {
        setCssVar("--bg", "#000")
        setCssVar("--text", "hsl(107.39deg 82.83% 47.02%)")
        setCssVar("--text2", "rgb(42 199 49)")
        setCssVar("--err", "red")
        setCssVar("--bgBlocker", "rgba(10, 10, 10, 0.9)")
        setCssVar("--bgTransparent1", "rgba(0, 0, 0, 0.1)")
        setCssVar("--LG1", "linear-gradient(87deg,#10f30f,#fff,#10f30f,#000000,#10f30f,#000000)")
        setCssVar("--mainFont", "WARGAMES")
    }

    constructor() {
        addEventListener("theme", (e) =&amp;gt; {
            this[e.detail]();
        })
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementing account for GamePlay platform based on RocketCraaftingServer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; fetch("http://maximumroulette.com/rocket/login", {
                  "headers": {
                    "accept": "application/json",
                    "accept-language": "en-US,en;q=0.9,ru;q=0.8",
                    "cache-control": "no-cache",
                    "content-type": "application/json",
                    "pragma": "no-cache"
                  },
                  "referrer": "http://maximumroulette.com/apps/my-admin/",
                  "referrerPolicy": "strict-origin-when-cross-origin",
                  "body": "{\"emailField\":\"zlatnaspirala@gmail.com\",
                    \"passwordField\":\"123123123\"}",
                  "method": "POST",
                  "mode": "cors",
                  "credentials": "omit"
                });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem with &amp;gt; 100Mb file size upload on github use this link for fbx animations&lt;br&gt;
(prepared in blender) you can open it in any 3d editor: &lt;a href="https://drive.google.com/drive/folders/194gsNMBvljJgK_2nyM4paA-veBZl8_Tf?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/drive/folders/194gsNMBvljJgK_2nyM4paA-veBZl8_Tf?usp=sharing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update deps&lt;/p&gt;

</description>
      <category>webgl</category>
      <category>threejs</category>
      <category>ammojs</category>
      <category>webrtc</category>
    </item>
    <item>
      <title>Video chat with Matrix-engine [standalone] raw yt video</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Wed, 27 Sep 2023 17:11:13 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/video-chat-with-matrix-engine-standalone-raw-yt-video-pn7</link>
      <guid>https://dev.to/zlatnaspirala/video-chat-with-matrix-engine-standalone-raw-yt-video-pn7</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=L5eaXP_VuyQ&amp;amp;ab_channel=javascriptfanatic"&gt;TY raw implementation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source code of example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @Author Nikola Lukic
 * @Description Matrix Engine Api Example.
 */

import App from "../program/manifest";
import * as matrixEngine from "../index.js";
let VT = matrixEngine.Engine.VT;

export var runThis = world =&amp;gt; {
  App.camera.SceneController = true;

  canvas.addEventListener('mousedown', (ev) =&amp;gt; {
    matrixEngine.raycaster.checkingProcedure(ev);
  });

  window.addEventListener('ray.hit.event', (ev) =&amp;gt; {
    console.log("You shoot the object! Nice!", ev)
    if(ev.detail.hitObject.physics.enabled == true) {
      ev.detail.hitObject.physics.currentBody.force.set(0, 0, 1000)
    }
  });

  var tex = {
    source: ["res/images/complex_texture_1/diffuse.png"],
    mix_operation: "multiply", // ENUM : multiply , divide ,
  };

  let gravityVector = [0, 0, -9.82];
  let physics = world.loadPhysics(gravityVector);
  // Add ground
  physics.addGround(App, world, tex);
  const objGenerator = (meObj) =&amp;gt; {
    var b2 = new CANNON.Body({
      mass: 1,
      linearDamping: 0.01,
      position: new CANNON.Vec3(0, -14.5, 15),
      shape: new CANNON.Box(new CANNON.Vec3(3, 3, 3))
    });
    physics.world.addBody(b2);
    meObj.physics.currentBody = b2;
    meObj.physics.enabled = true;
  }
  // objGenerator(1)

  matrixEngine.Engine.activateNet();
  // let ENUMERATORS = matrixEngine.utility.ENUMERATORS;
  addEventListener('stream-loaded', (e) =&amp;gt; {
    var _ = document.querySelectorAll('.media-box')
    var name = "videochat-" + e.detail.data.userId;
    _.forEach((i) =&amp;gt; {
      // App.network.connection.userid  REPRESENT LOCAL STREAM 
      if(e.detail.data.userId != App.network.connection.userid) {
        // This is video element!
        world.Add("cubeLightTex", 3, name, tex);
        App.scene[name].position.x = 0;
        App.scene[name].position.z = -20;
        // App.scene[name].rotx = 45
        // App.scene[name].rotation.rotz = -90
        App.scene[name].LightsData.ambientLight.set(1, 1, 1);
        App.scene[name].net.enable = true;
        App.scene[name].net.activate();
        App.scene[name].streamTextures = matrixEngine.Engine.DOM_VT(i.children[1])
        objGenerator(App.scene[name])

        App.CUSTOM_TIMER = setInterval(() =&amp;gt; {
          try {
            if(typeof App.scene[name] !== 'undefined' &amp;amp;&amp;amp; typeof App.scene[name].geometry !== 'undefined') {
              App.scene[name].geometry.texCoordsPoints.front.right_top.x += 0.001;
              App.scene[name].geometry.texCoordsPoints.front.left_bottom.x += 0.001;
              App.scene[name].geometry.texCoordsPoints.front.left_top.x += 0.001;
              App.scene[name].geometry.texCoordsPoints.front.right_bottom.x += 0.001;
            } else {
              clearInterval(App.CUSTOM_TIMER)
              App.CUSTOM_TIMER = null;
            }
          } catch(err) {
            clearInterval(App.CUSTOM_TIMER)
            App.CUSTOM_TIMER = null;
          }
        }, 1);

        addEventListener('net.remove-user', (event) =&amp;gt; {
          var n = "videochat-" + event.detail.data.userid;
          if(typeof App.scene[n] !== 'undefinde' &amp;amp;&amp;amp;
            typeof App.scene[n].CUSTOM_FLAG_PREVENT_DBCALL === 'undefined') {
            App.scene[n].CUSTOM_FLAG_PREVENT_DBCALL = true;
            App.scene[n].selfDestroy(1)
          }
        })
      } else {
        // own stream 
        function onLoadObj(meshes) {
          App.meshes = meshes;
          matrixEngine.objLoader.initMeshBuffers(world.GL.gl, App.meshes.TV);
          setTimeout(function() {
            world.Add("obj", 1, "TV", tex, App.meshes.TV);
            App.scene.TV.position.setPosition(-9, 4, -15)
            App.scene.TV.rotation.rotateY(90);
            App.scene.TV.LightsData.ambientLight.set(1, 1, 1);
            App.scene.TV.streamTextures = new matrixEngine.Engine.DOM_VT(i.children[1]);
          }, 1000)
        }
        matrixEngine.objLoader.downloadMeshes({TV: "res/3d-objects/balltest2.obj"}, onLoadObj);
      }
    })
  })

  world.Add("cubeLightTex", 3, "outsideBox2", tex);

  App.scene.outsideBox2.position.x = 0;
  App.scene.outsideBox2.position.y = 2;
  App.scene.outsideBox2.position.z = -24;
  App.scene.outsideBox2.rotation.rotationSpeed.y = 20
  App.scene.outsideBox2.rotation.rotx = 45
  App.scene.outsideBox2.streamTextures = new VT(
    "res/video-texture/me.mkv"
  );

  App.scene.outsideBox2.glBlend.blendEnabled = true;
  App.scene.outsideBox2.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[6];
  App.scene.outsideBox2.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[6];

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;DEMO: *&lt;/em&gt;&lt;br&gt;
&lt;a href="https://maximumroulette.com/apps/matrix-engine/query-build.html?u=matrix_chat_room"&gt;MatrixEngine video chat&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webgl</category>
      <category>webrtc</category>
      <category>matrixengine</category>
      <category>chat</category>
    </item>
    <item>
      <title>Matrix-engine [1.8.4]</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Fri, 28 Oct 2022 17:28:39 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/matrix-engine-184-421f</link>
      <guid>https://dev.to/zlatnaspirala/matrix-engine-184-421f</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTEb3qAc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28js52rzl5h9q5byl6cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTEb3qAc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28js52rzl5h9q5byl6cg.png" alt="Image description" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About Matrix Engine project&lt;br&gt;
Name: MATRIX-ENGINE 1.8.1&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STATUS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Integrated PWA addToHomePage/cache/] ✔&lt;/li&gt;
&lt;li&gt;[Integrated raycast (hit trigger detect), bvh animation] ✔&lt;/li&gt;
&lt;li&gt;[Basic Physics implementation based on cannon.js] ✔&lt;/li&gt;
&lt;li&gt;[FirstPersonController/SceneController Drag and navigation scene] ✔&lt;/li&gt;
&lt;li&gt;[Shadows vs lights (GLSL)] ✔
*&lt;em&gt;Description *&lt;/em&gt;ℹ
This is small but inspiring project. The benefits of this project is offering an overview of the entire application logic, easy native implementations (hybrid app), object structural. Thanks to Mr.Keestu i use (gl-program-structure) new version of glmatrix (2.0). Push&amp;amp;Pop matrix just like in opengles 1.1. Also can be downgraded to openGLES 1.1. webGL Lightweight library based on glmatrix engine. For multiplayer used webRTC done with io socket. Physics done with last version of cannon.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Limitation *&lt;/em&gt;⚠&lt;br&gt;
Basic implementation for physics (Cube, Sphere)&lt;br&gt;
Raycast not work after walk behind the object in first person mode&lt;br&gt;
Only static object cast spot light in right way for now.&lt;br&gt;
Need general more improvement on GLSL part.&lt;br&gt;
Next Features 🔜&lt;br&gt;
General improvements in Lights section. Shaders must be improved based on work Links -&amp;gt; &lt;a href="https://webglfundamentals.org/webgl/lessons/"&gt;https://webglfundamentals.org/webgl/lessons/&lt;/a&gt;&lt;br&gt;
For npm users recommended&lt;br&gt;
Use starter project: &lt;a href="https://github.com/zlatnaspirala/matrix-engine-starter"&gt;https://github.com/zlatnaspirala/matrix-engine-starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;with command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i&lt;br&gt;
npm run build.all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project template in matrix-engine-starter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Slot Mashine &lt;a href="https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-slot/index.html"&gt;https://maximumroulette.com/apps/matrix-engine-starter/projects/matrix-slot/index.html&lt;/a&gt;&lt;br&gt;
Live Demos&lt;br&gt;
&lt;a href="https://maximumroulette.com/apps/matrix-engine/examples-build.html"&gt;https://maximumroulette.com/apps/matrix-engine/examples-build.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com/apps/matrix-engine/app-build.html"&gt;https://maximumroulette.com/apps/matrix-engine/app-build.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to use it from npm services [codepen examples]&lt;br&gt;
[1.7.9] Lights - Who to use matrix-engine on codepen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/zlatnaspirala/full/OJZXMWR"&gt;https://codepen.io/zlatnaspirala/full/OJZXMWR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BHV Pseudo Skeletal animation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/zlatnaspirala/full/OJQdGVM"&gt;https://codepen.io/zlatnaspirala/full/OJQdGVM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Physics (cannon.js)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/zlatnaspirala/pen/rNvLGxE?editors=0010"&gt;https://codepen.io/zlatnaspirala/pen/rNvLGxE?editors=0010&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install dependencies&lt;br&gt;
Matrix engine keep minimum dependency.&lt;/p&gt;

&lt;p&gt;uglify-js, minify&lt;br&gt;
browserify, watchify&lt;br&gt;
&lt;code&gt;&lt;br&gt;
  npm run install.dep&lt;br&gt;
  npm i&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/note"&gt;@note&lt;/a&gt;: For windows users maybe you will need to add browserify to the env PATH if you got errors on commands npm run build.*.&lt;/p&gt;

&lt;p&gt;Help for localhost dev stage&lt;br&gt;
Build Application bundle script&lt;br&gt;
From [1.8.0] you can use build for develop with watch task:&lt;/p&gt;

&lt;p&gt;npm run examples&lt;br&gt;
npm run app&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/note"&gt;@note&lt;/a&gt;: If you use unsecured http protocol no build needed at all just navigate to the html file who loade script with type=module. No need for this any more but you can use it.&lt;/p&gt;

&lt;p&gt;For production/public server you will use npm run build.XXX commands. and then upload project to the usually /var/www/html/.&lt;/p&gt;

&lt;p&gt;app-build.html , examples-build.html loads compiled javascript type text/javascript.&lt;/p&gt;

&lt;p&gt;Build entry App.js&lt;/p&gt;

&lt;p&gt;npm run build.app&lt;br&gt;
Now navigate to the app-build.html page.&lt;/p&gt;

&lt;p&gt;Build entry App-Examples.js&lt;br&gt;
  npm run build.examples&lt;br&gt;
Now navigate to the examples-build.html page.&lt;/p&gt;

&lt;p&gt;Build just library&lt;br&gt;
&lt;code&gt;&lt;br&gt;
  npm run build.lib&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Build with uglify&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build.app.ugly;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Build ALL&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm  run build.all;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After all for production is recommended to use compressed script.&lt;/p&gt;

&lt;p&gt;Production Final (bash):&lt;br&gt;
./compress&lt;br&gt;
Switch example with url params&lt;br&gt;
Usefull also for production for switching whole pages/apps. &lt;a href="https://localhost/matrix-engine/query.html?u=adding_color_cube"&gt;https://localhost/matrix-engine/query.html?u=adding_color_cube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://localhost/matrix-engine/query-build.html?u=adding_color_cube"&gt;https://localhost/matrix-engine/query-build.html?u=adding_color_cube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code access:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;const QueryString = matrixEngine.utility.QueryString;&lt;br&gt;
Take a look at query-build.html&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;List of examples:&lt;/strong&gt;&lt;br&gt;
Adding color cube&lt;br&gt;
Adding color pyramyde&lt;br&gt;
Adding color square&lt;br&gt;
Adding tex square with raycast&lt;br&gt;
Adding color triangle&lt;br&gt;
Adding geometry&lt;br&gt;
Adding multi (compose) textures&lt;br&gt;
Adding square texture&lt;br&gt;
Blending&lt;br&gt;
Audion amnipulation&lt;br&gt;
Camera texture (stream texture)&lt;br&gt;
Cube&lt;br&gt;
Cube Geometry&lt;br&gt;
Cube Light &amp;amp; texture&lt;br&gt;
Cube light dynamic&lt;br&gt;
Custom texture&lt;br&gt;
First Person controller&lt;br&gt;
Load obj files&lt;br&gt;
Object animation -morh sequence&lt;br&gt;
Object animation mesh indices calculation&lt;br&gt;
JS1Kilo examples implementation&lt;br&gt;
Porting 2D canvas (Active textures)&lt;br&gt;
Sphere geometry&lt;br&gt;
Texture uv manipulation&lt;br&gt;
Videos textures&lt;br&gt;
Physics Cube with force on raycast trigger&lt;br&gt;
Physics Sphere&lt;br&gt;
BVH loader, animation play&lt;br&gt;
Load obj sequences&lt;/p&gt;

&lt;p&gt;Features description&lt;br&gt;
Camera config&lt;br&gt;
In ./program/manifest.js. Access is App.camera. Note: One of params FirstPersonController or SceneController must be false.&lt;/p&gt;

&lt;p&gt;FirstPersonController is classic first person view with movement WASD and mouse look.&lt;br&gt;
SceneController use direct input WASD. To make camera angle view change press shift to enable camera angle. Middle mouse button will enable drag scene to left/right/top/down. Mouse middle wheel change work only when shift is pressed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;camera: {&lt;br&gt;
    viewAngle: 45,&lt;br&gt;
    nearViewpoint: 0.1,&lt;br&gt;
    farViewpoint: 1000,&lt;br&gt;
    edgeMarginValue: 100,&lt;br&gt;
    FirstPersonController: false,&lt;br&gt;
    SceneController: false,&lt;br&gt;
    sceneControllerDragAmp: 0.1,&lt;br&gt;
    sceneControllerDragAmp: 0.1,&lt;br&gt;
    speedAmp: 0.5,&lt;br&gt;
    sceneControllerEdgeCameraYawRate: 3,&lt;br&gt;
    sceneControllerWASDKeysAmp: 0.1&lt;br&gt;
  },&lt;br&gt;
&lt;strong&gt;Light And Shadows [1.7.6]&lt;/strong&gt;&lt;br&gt;
activateShadows works only for cube for now.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; world.Add("cubeLightTex", 1, "myCube4", textuteImageSamplers);
  App.scene.myCube4.activateShadows();
  App.scene.myCube4.shadows.activeUpdate();
  App.scene.myCube4.shadows.animatePositionY();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wanna color vertex but with direction and ambient light then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Simple direction light
world.Add("cubeLightTex", 1, "myCube7", textuteImageSamplersTest);
App.scene.myCube7.position.setPosition(3,3,-11);
App.scene.myCube7.geometry.colorData.SetGreenForAll(0.5)
App.scene.myCube7.geometry.colorData.SetRedForAll(0.5)
App.scene.myCube7.geometry.colorData.SetBlueForAll(0.5)
App.scene.myCube7.deactivateTex();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Make square pattern&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  // Custom generic textures. Micro Drawing.
  // Example for arg shema square for now only.
  var options = {
    squareShema: [4,4],
    pixels: new Uint8Array(4 * 4 * 4),
    style: {
      type: 'chessboard',
      color1: 0,
      color2: 255
    }
  };

  App.scene.myCube9.textures.push(
    App.scene.myCube9.createPixelsTex(options)
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Physics&lt;/strong&gt;&lt;br&gt;
Physics based on cannon.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support list :&lt;/strong&gt; 😇&lt;/p&gt;

&lt;p&gt;cube&lt;br&gt;
sphere&lt;/p&gt;

&lt;p&gt;Example with physics and raycast hit detect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; App.camera.SceneController = true;

  canvas.addEventListener('mousedown', (ev) =&amp;gt; {
    matrixEngine.raycaster.checkingProcedure(ev);
  });

  window.addEventListener('ray.hit.event', (ev) =&amp;gt; {
    console.log("You shoot the object! Nice!", ev)

    /**
     * Physics force apply
     */
     if (ev.detail.hitObject.physics.enabled == true) {
      ev.detail.hitObject.physics.currentBody.force.set(0,0,1000)
     }
  });

  var tex = {
    source: ["res/images/complex_texture_1/diffuse.png"],
    mix_operation: "multiply",
  };

  // Load Physics world!
  let gravityVector = [0, 0, -9.82];
  let physics = world.loadPhysics(gravityVector);
  // Add ground
  physics.addGround(App, world, tex);
  world.Add("cubeLightTex", 1, "CUBE", tex);
  var b = new CANNON.Body({
    mass: 5,
    position: new CANNON.Vec3(0, -15, 2),
    shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1))
  });
  physics.world.addBody(b);
  // Physics
  App.scene.CUBE.physics.currentBody = b;
  App.scene.CUBE.physics.enabled = true;

  const objGenerator = (n) =&amp;gt; {
    for(var j = 0;j &amp;lt; n;j++) {

      setTimeout(() =&amp;gt; {
        world.Add("cubeLightTex", 1, "CUBE" + j, tex);
        var b2 = new CANNON.Body({
          mass: 1,
          linearDamping: 0.01,
          position: new CANNON.Vec3(1, -14.5, 15),
          shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1))
        });

        physics.world.addBody(b2);
        App.scene['CUBE' + j].physics.currentBody = b2;
        App.scene['CUBE' + j].physics.enabled = true;
      }, 1000 * j)
    }
  }

  objGenerator(100)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt; [1.8.0]&lt;/p&gt;

&lt;p&gt;Networking based on webRTC. If you wanna use multiplayer mode you need to run intro folder networking/ next commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; npm i
 node matrix-server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Networking Support Methods list: ✅😇&lt;br&gt;
Any scene object: ➡ position SetX() SetY() SetZ() ➡ rotation.rotateX() rotateY() rotateZ()&lt;/p&gt;

&lt;p&gt;Cube, Sphere, Square ➡ geometry.setScale() ➡ geometry.setScaleByY() ➡ geometry.setScaleByZ() ➡ geometry.setScaleByZ() ➡ geometry.setTexCoordScaleFactor()&lt;/p&gt;

&lt;p&gt;Pyramid ➡ geometry.setScale() ➡ geometry.setSpitz()&lt;/p&gt;

&lt;p&gt;Networking minimal example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export var runThis = world =&amp;gt; {

  world.Add("pyramid", 1, "MyCubeTex");
  world.Add("square", 1, "MyColoredSquare1");

  // Must be activate
  matrixEngine.Engine.activateNet();

  // Must be activate for scene objects also.
  // This is only to force avoid unnecessary networking emit!
  App.scene.MyCubeTex.net.enable = true;
  App.scene.MyCubeTex.net.activate();

  App.scene.MyColoredSquare1.net.enable = true;
  App.scene.MyColoredSquare1.net.activate();

  // Just call it normally
  App.scene.MyCubeTex.position.SetZ(-8);
  App.scene.MyColoredSquare1.position.SetZ(-8);

};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is perfect solution webGL vs webRTC. Origin code used broadcaster class from visual-ts game engine project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom textures&lt;/strong&gt;&lt;br&gt;
We just override function for texture executing code. Next level is full custom opportunity, geometry, collision, networking etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
App.scene.MySquareTexure1.custom.gl_texture = function (object, t) {
  world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.textures[t]);
  world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MAG_FILTER, world.GL.gl.LINEAR);
  world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MIN_FILTER, world.GL.gl.LINEAR);
  world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_S, world.GL.gl.CLAMP_TO_EDGE);
  world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_T, world.GL.gl.CLAMP_TO_EDGE);

  world.GL.gl.texImage2D(
    world.GL.gl.TEXTURE_2D,
    0,                         // Level of details
    world.GL.gl.RGBA,          // Format
    world.GL.gl.RGBA,
    world.GL.gl.UNSIGNED_BYTE, // Size of each channel
    object.textures[t].image
  );

  world.GL.gl.generateMipmap(world.GL.gl.TEXTURE_2D);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;BVH Matrix Skeletal *&lt;/em&gt;[1.5.0]&lt;br&gt;
New deps pack bvh-loader. It is bvh parser created for matrix-engine but can be used for any other graphics language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const options = {
    world: world,
    autoPlay: true,
    myFrameRate: 10,
    showOnLoad: false, // if autoPLay is true then showOnLoad is inactive.
    type: 'ANIMATION', // "TPOSE' | 'ANIMATION'
    loop: 'playInverse', // true | 'stopOnEnd' | 'playInverse' | 'stopAndReset'
    globalOffset: [-30, -180, -155],
    skeletalBoneScale: 6,
    boneNameBasePrefix: 'backWalk',
    skeletalBlend: { paramDest: 7, paramSrc: 6 }, // remove arg for no blend
    boneTex: {
      source: [
        "res/icons/512.png"
      ],
      mix_operation: "multiply",
    },
    // pyramid | triangle | cube | square | squareTex | cubeLightTex | sphereLightTex'
    drawTypeBone: 'squareTex' 
  };

  const filePath = 'https://raw.githubusercontent.com/zlatnaspirala/bvh-loader/main/javascript-bvh/example.bvh';

  var myFirstBvhAnimation = new matrixEngine.MEBvhAnimation(filePath, options);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live demo &lt;a href="https://codepen.io/zlatnaspirala/pen/OJQdGVM"&gt;https://codepen.io/zlatnaspirala/pen/OJQdGVM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Raycast&lt;/strong&gt;&lt;br&gt;
cube , square, triangle, obj (ObjLoader) [1.8.4] From 1.8.4 raycast hit trigger works for obj's.&lt;/p&gt;

&lt;p&gt;Raycast works fine also in firstPersonCamera operation. Raycast work perfect after local single rotation x, y, or z. Combination rotx and roty works , roty and rotz only with rotx = 180 for now. Bug if walk behind object then turn arround and try raycast but no work for now.&lt;/p&gt;

&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; canvas.addEventListener('mousedown', (ev) =&amp;gt; {
    matrixEngine.raycaster.checkingProcedure(ev);
  });

  canvas.addEventListener('ray.hit.event', (ev) =&amp;gt; {
    alert("You shoot the object! Nice")
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;First person controller&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // In one line activate also deactivate.
  App.camera.FirstPersonController = true;
Animated female droid (morph targets):
// Obj Loader
function onLoadObj(meshes) {

  // No need from [1.8.2]
  // App.meshes = meshes;
  for (const key in App.meshes) {
    matrixEngine.objLoader.initMeshBuffers(world.GL.gl, App.meshes[key]);
  }

  textuteImageSamplers2 = {
    source: ['res/images/RustPaint.jpg'],
    mix_operation: 'multiply'
  };

  setTimeout(function () {
    var animation_construct = {
      id: 'female',
      meshList: meshes, // from [1.8.2]
      sumOfAniFrames: 18,
      currentAni: 0,
      speed: 3
    };

    world.Add('obj', 1, 'female', textuteImageSamplers2, App.meshes.female, animation_construct);

    App.scene.female.position.y = -3;
    App.scene.female.rotation.rotationSpeed.z = 20;
    App.scene.female.position.z = -13;
    // App.scene.armor.mesh.setScale(5)
  }, 100);
}

// Custom list 1, 3, 5, 9
matrixEngine.objLoader.downloadMeshes(
  {
    female: 'res/3d-objects/female/female_000001.obj',
    female1: 'res/3d-objects/female/female_000003.obj',
    female2: 'res/3d-objects/female/female_000005.obj',
    female3: 'res/3d-objects/female/female_000009.obj',
    ...
  },
  onLoadObj
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;// From [1.8.2] you can use &lt;code&gt;makeObjSeqArg&lt;/code&gt;&lt;br&gt;
matrixEngine.objLoader.downloadMeshes(&lt;br&gt;
  matrixEngine.objLoader.makeObjSeqArg(&lt;br&gt;
    { id: objName,&lt;br&gt;
      path: "res/bvh-skeletal-base/swat-guy/seq-walk/low/swat",&lt;br&gt;
      from : 1, to: 34 }),&lt;br&gt;
  onLoadObj&lt;br&gt;
);&lt;br&gt;
&lt;strong&gt;Blending&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Use it
App.scene.female.glBlend.blendEnabled = true;
App.scene.female.glBlend.blendParamSrc = ENUMERATORS.glBlend.param[4];
App.scene.female.glBlend.blendParamDest = ENUMERATORS.glBlend.param[4];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load Obj with UV map (Blender export tested):&lt;br&gt;
For more details dee this example script: load_obj_file.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Video texture&lt;/strong&gt;:&lt;br&gt;
world.Add('cubeLightTex', 1, 'TV', textuteImageSamplers, App.meshes.TV);&lt;br&gt;
App.scene.TV.streamTextures = new VIDEO_TEXTURE('Galactic Expansion Fractal Morph [Official Video]');&lt;br&gt;
Camera texture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App.scene.TV.streamTextures = new ACCESS_CAMERA('webcam_beta');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;MatrixBVHCharacter *&lt;/em&gt;(MEBvhAnimation)&lt;/p&gt;

&lt;p&gt;MatrixBVHCharacter feature use class matrixEngine.MEBvhAnimation. Its load primitives for bvh skeletal. MatrixBVHCharacter is proccess where we load pre defined skelatal obj parts(head, neck, legs...) .&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/note"&gt;@note&lt;/a&gt; Human character failed for noe but func works.&lt;br&gt;
Nice for primitive obj mesh bur rig must have nice description of position/rotation. In maximo skeletal bones simple not fit. If you pripare bones you can get nice bvh obj adaptation for animations.&lt;/p&gt;

&lt;p&gt;Example Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const options = {
    world: world,                    // [Required]
    autoPlay: true,                  // [Optimal]
    showOnLoad: false,               // [Optimal] if autoPLay is true then showOnLoad is inactive.
    type: 'ANIMATION',               // [Optimal] 'ANIMATION' | "TPOSE'
    loop: 'playInverse',             // [Optimal] true | 'stopOnEnd' | 'playInverse' | 'stopAndReset'
    globalOffset: [-30, -180, -155], // [Optimal]  for 1.5 diff from obj seq anim
    skeletalBoneScale: 2,            // [Optimal]
    /*skeletalBlend: {               // [Optimal] remove arg for no blend
      paramDest: 4,
      paramSrc: 4
    },*/
    boneTex: {
      source: [
        "res/images/default/default-pink.png",
      ],
      mix_operation: "multiply",
    },
    drawTypeBone: "matrixSkeletal",
    matrixSkeletal: "res/bvh-skeletal-base/y-bot/matrix-skeletal/",
    objList: ['spine', 'hips', 'head'] ,

    matrixSkeletalObjScale: 80,       // [Optimal]

    // Can be predefined `MatrixSkeletal` prepared skeletal obj parts/bones.
    // Can be primitives:
    // pyramid | triangle | cube | square | squareTex | cubeLightTex | sphereLightTex

    // New optimal arg
    // Sometime we need more optimisation
    ignoreList: ['spine1'],
    ifNotExistDrawType: 'triangle'
  };

  const filePath = "res/bvh/Female1_B04_StandToWalkBack.bvh";
  var myFirstBvhAnimation = new matrixEngine.MEBvhAnimation(filePath, options);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is folder for obj parts (head arm legs ...) Filenames are simplefield like head.obj , arm.obj without any prefix from constructor...&lt;/p&gt;

&lt;p&gt;matrixSkeletal: "res/bvh-skeletal-base/y-bot/matrix-skeletal/",&lt;/p&gt;

&lt;p&gt;Take a look example: matrix_skeletal.js.&lt;/p&gt;

&lt;p&gt;Character (ObjLoader/morph targets)&lt;br&gt;
This good in runtime bad for loading procedure.&lt;/p&gt;

&lt;p&gt;How to update character animation? Maximo -&amp;gt; download dea or fbx -&amp;gt; import intro blender Import multi or one animation. -&amp;gt; blender export -&amp;gt; obj (animation)&lt;/p&gt;

&lt;p&gt;This is new feature from [1.8.2]. Take a look at : load_obj_sequence.js&lt;/p&gt;

&lt;p&gt;For now engine use objLoader to load all morphs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  matrixEngine.objLoader.downloadMeshes(
      matrixEngine.objLoader.makeObjSeqArg(
        {
          id: objName,
          path: "res/bvh-skeletal-base/swat-guy/anims/swat-multi",
          from: 1,
          to: 61
        }),
      onLoadObj
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in onLoadObj :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var animArg = {
    id: objName,
    meshList: meshes,
    // sumOfAniFrames: 61, No need if `animations` exist!
    currentAni: 0,
    // speed: 3, No need if `animations` exist!
    // upgrade - optimal
    animations: {
      active: 'walk',
      walk: {
        from: 0,
        to: 35,
        speed: 3
      },
      walkPistol: {
        from: 36,
        to: 60,
        speed: 3
      }
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Texture editor (runtime):&lt;br&gt;
Using Vjs3 with Editor use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; App.scene.outsideBox.streamTextures = new Vjs3(
  "./2DTextureEditor/actual.html",
  "actualTexture"
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running Editor Tool&lt;br&gt;
npm run run.tex.editor&lt;br&gt;
// or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run te
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating 2d texture direct on page at the end run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build.tex.editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to make build final pack.&lt;/p&gt;

&lt;p&gt;Imports note we can use any canvas 2d app [anyCanvas] .&lt;br&gt;
In examples:&lt;/p&gt;

&lt;p&gt;porting2d.js [Old VJS] Example of anyCanvas&lt;br&gt;
porting_text.js [Vjs3]&lt;br&gt;
porting2d_particle.js [Vjs3]&lt;br&gt;
It is very powerfull tool!&lt;/p&gt;

&lt;p&gt;Research Vjs3 source examples at: &lt;a href="https://github.com/zlatnaspirala/visualjs"&gt;https://github.com/zlatnaspirala/visualjs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On NPM Service npm i visual-js , matrix engine already have visual-js , visual-js-server editor backend part.&lt;/p&gt;

&lt;p&gt;To show/hide iframe use: App.scene.outsideBox - is any object who have streamTextures LOADED with 2DCANVAS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App.scene.outsideBox.streamTextures.showTextureEditor();
E('HOLDER_STREAMS').style.display = 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access to the [any] canvas2d program: anyCanvas(path-of-html,name-of-canvas)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; App.scene.outsideBox.streamTextures = new anyCanvas(
      "./apps/funny-slot/",
      "HELLO_WORLD")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live editor [actual.js predefined]&lt;br&gt;
Texture-Editor&lt;/p&gt;

&lt;p&gt;Old VJS loading with anyCanvas()&lt;br&gt;
Texture-Editor&lt;/p&gt;

&lt;p&gt;Old Live demo: Video and webcam works at: &lt;a href="https://maximumroulette.com/webgl2/examples.html"&gt;https://maximumroulette.com/webgl2/examples.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changes&lt;/strong&gt;:&lt;br&gt;
From [1.8.0]&lt;br&gt;
Added watchify. We have support for real time connections based on webRTC. You must work on https protocol even in localhost. Change in program/manifest net = false if you dont wanna use networking.&lt;/p&gt;

&lt;p&gt;Node.js Multiplayer Server based on webRTC. Take a look at the folder ./netwotking.&lt;/p&gt;

&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd networking
node matrix.server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wanna in terminal popup then run (bash/work on win also if you have bash) dedicated.sh./ or dedicated.bat.&lt;/p&gt;

&lt;p&gt;From [1.7.11]&lt;br&gt;
No need for: // &lt;code&gt;matrixEngine.Engine.load_shaders('shaders/shaders.html');&lt;/code&gt;Initial Shaders now loads from code (inside engine). No need any action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PWA Fully runned&lt;/strong&gt;&lt;br&gt;
Integrated Add to Home page and regular html5 page options. In same time fixed all autoplay audio and video context construction. It is good to consult pwa test on page. Best way is to keep it on 100% pass. pwa-powered&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Secured *&lt;/em&gt;🛡&lt;br&gt;
No Dependabot alerts opened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credits &amp;amp;&amp;amp; Licence:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Video material used from :From youtube.com : Electric sheep - a facinating animated flame fractal TheMrNgaard Creative Commons Attribution licence (reuse allowed)&lt;br&gt;
Project Base Structure inspired by Copyright (C) 2014 Tappali Ekanathan Keestu (&lt;a href="mailto:keestu@gmail.com"&gt;keestu@gmail.com&lt;/a&gt;) GNU General Public License&lt;br&gt;
Textures download from &lt;a href="http://textures.com"&gt;http://textures.com&lt;/a&gt;&lt;br&gt;
Dinamic texture bitcoin used from: Author:Ioannis Cherouvim GitHub:cherouvim Reddit:/r/cherouvim Website:cherouvim.com Compo:canvas Demo link:&lt;a href="https://js1k.com/2017-magic/demo/2853"&gt;https://js1k.com/2017-magic/demo/2853&lt;/a&gt; Shortlink:&lt;a href="https://js1k.com/2853"&gt;https://js1k.com/2853&lt;/a&gt;&lt;br&gt;
Female 3d Object &lt;a href="http://www.blendswap.com/blends/view/26225"&gt;http://www.blendswap.com/blends/view/26225&lt;/a&gt; Creative Commons Attribution 3.0 &lt;a href="http://www.blendswap.com/users/view/AndresCuccaro"&gt;http://www.blendswap.com/users/view/AndresCuccaro&lt;/a&gt;&lt;br&gt;
&lt;a href="https://freestocktextures.com/texture/bark-wood-plant,122.html"&gt;https://freestocktextures.com/texture/bark-wood-plant,122.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Necolo/raycaster"&gt;https://github.com/Necolo/raycaster&lt;/a&gt;&lt;br&gt;
Great &lt;a href="https://www.mixamo.com/"&gt;https://www.mixamo.com/&lt;/a&gt;&lt;br&gt;
Player character &lt;a href="https://www.mixamo.com/#/?page=1&amp;amp;query=walk&amp;amp;type=Motion%2CMotionPack"&gt;https://www.mixamo.com/#/?page=1&amp;amp;query=walk&amp;amp;type=Motion%2CMotionPack&lt;/a&gt;&lt;br&gt;
BVH collections from: Special thanks to the CMU Graphics Lab Motion Capture Database which provided the data &lt;a href="http://mocap.cs.cmu.edu/%60"&gt;http://mocap.cs.cmu.edu/`&lt;/a&gt;&lt;br&gt;
Used in examples: BLACK FLY by Audionautix | &lt;a href="http://audionautix.com"&gt;http://audionautix.com&lt;/a&gt; Music promoted by &lt;a href="https://www.free-stock-music.com"&gt;https://www.free-stock-music.com&lt;/a&gt; Creative Commons Attribution-ShareAlike 3.0 Unported &lt;a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en_US"&gt;https://creativecommons.org/licenses/by-sa/3.0/deed.en_US&lt;/a&gt;&lt;br&gt;
Networking based on &lt;a href="https://github.com/muaz-khan/RTCMultiConnection"&gt;https://github.com/muaz-khan/RTCMultiConnection&lt;/a&gt;&lt;br&gt;
Keywords&lt;br&gt;
physicscannon.jsbvh-glmatrxbvh.jsbvh-skeletalbvh-webglbvh-loaderbvh-animationraycastraycast-glmatrixvanilla-jswebcam-texturevideo-texturecanvastexturessceneopengleswebglwebgl2glmatrixopengles23djavascriptopengles3matrixECMA6no-build-devbuild-prodbrowserifymatrix-enginealternativethree.js alternative&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webgl</category>
      <category>glmatrix</category>
      <category>bvh</category>
    </item>
    <item>
      <title>npm package `visual-ts`</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Sun, 02 May 2021 00:24:43 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/npm-package-visual-ts-1hk7</link>
      <guid>https://dev.to/zlatnaspirala/npm-package-visual-ts-1hk7</guid>
      <description>&lt;p&gt;Visual-Ts-Game-Engine Package Link&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/visual-ts"&gt;https://www.npmjs.com/package/visual-ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live:&lt;br&gt;
&lt;a href="https://codepen.io/zlatnaspirala/pen/NWdZJQJ"&gt;https://codepen.io/zlatnaspirala/pen/NWdZJQJ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New example repo : &lt;/p&gt;

&lt;p&gt;It is the strarter for &lt;code&gt;visual-ts&lt;/code&gt;&lt;br&gt;
   &lt;a href="https://github.com/zlatnaspirala/visual-ts-examples"&gt;https://github.com/zlatnaspirala/visual-ts-examples&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AppConfig extends V.ClientConfig {

  constructor(gameList: any) {
    super(gameList);
    console.info("Make changes on Application Config.");
  }

  /**
     * @description
     * You can use prop from exstended ClientConfig class
     * @name getDrawRefference
     * @returns string
     */
  public getDrawRefference(): string {
    // Do something...
    console.log("Setup draw type")
    // return "diametric-fullscreen"
    // return this.drawReference;
    return "frame"
  }
}

class Demo1 implements V.Interface.IGamePlayModelNoPlayer {

  public gameName: string = "Demo 1 - Add new element";
  public version: number = 1.0;
  public playerCategory = 0x0002;
  public staticCategory = 0x0004;

  public starter: V.Starter;
  public myFirstGamePlayObject: V.Matter.Body | any = undefined;

  constructor(starter: V.Starter) {
    this.starter = starter;
  }

  public attachAppEvents() {
    const root = this;
    root.createMyElements(true);
    root.addGround();
    console.info("App event test");
  }

  public addGround() {
    const newStaticElement: V.Type.worldElement = V.Matter.Bodies.rectangle(
      400,
      550,
      1000,
      90,
      {
        isStatic: true,
        isSleeping: false,
        label: "ground",
        collisionFilter: {
          group: this.staticCategory,
        } as any,
        render: {
          // visualComponent: new TextureComponent("imgGround",[require("./imgs/backgrounds/wall3.png")]),
          sprite: {
            olala: true,
          },
        } as any | Matter.IBodyRenderOptions,
      }
    );

    //  (newStaticElement.render as any).visualComponent.setVerticalTiles(2).
    //    setHorizontalTiles(1);
    this.starter.AddNewBodies([newStaticElement] as V.Type.worldElement);
  }

  public createMyElements(addToScene: boolean) {
    const playerRadius = 50;
    this.myFirstGamePlayObject = V.Matter.Bodies.circle(
      400,
      100,
      playerRadius,
      {
        label: "MYFIRSTOBJECT",
        density: 0.0005,
        friction: 0.01,
        frictionAir: 0.06,
        restitution: 0.3,
        ground: true,
        jumpCD: 0,
        portal: -1,
        collisionFilter: {
          category: this.playerCategory,
        } as any,
        render: {
          fillStyle: "blue",
          sprite: {
            xScale: 1,
            yScale: 1,
          },
        } as any,
      } as Matter.IBodyDefinition
    );
    this.myFirstGamePlayObject.collisionFilter.group = -1;

    // hardcode for now
    this.myFirstGamePlayObject.render.sprite.xScale = 0.2;
    this.myFirstGamePlayObject.render.sprite.yScale = 0.2;

    if (addToScene) {
      this.myFirstGamePlayObject.id = 2;
      this.starter.AddNewBodies(
        this.myFirstGamePlayObject as V.Type.worldElement
      );
      console.info('myFirstGamePlayObject body created from "https://cdn.skypack.dev/dead".');
    }
  }

  protected destroyGamePlayPlatformer() {
    this.starter.destroyGamePlay();
    this.starter.deattachMatterEvents();
  }
}

// Make instance - Run app

const gameInfo = {
  name: "Demo 1h",
  title: "Create game with module visual-ts. ",
};

const gamesList: any[] = [
  gameInfo,
];

let injectedConfig: V.Interface.IClientConfig = new AppConfig(gamesList);
const master = new V.IocSinglePlayerMode(null, injectedConfig);

master.singlton(Demo1, master.get.Starter);
master.get.Demo1.attachAppEvents();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>Cross-K Visual GUI App engine 
Based on kivy 2.0 Python3</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Fri, 09 Apr 2021 15:07:58 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/cross-k-visual-gui-app-engine-based-on-kivy-2-0-python3-250c</link>
      <guid>https://dev.to/zlatnaspirala/cross-k-visual-gui-app-engine-based-on-kivy-2-0-python3-250c</guid>
      <description>&lt;p&gt;Based on kivy 2.0 python framework. GPL-3.0 License with avavailable source code.&lt;br&gt;
CrossK is a small but conspiratorial app engine based on kivy opengles2.0 in background.&lt;br&gt;
Created to make future fast and quick. No builds losing time any more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zlatnaspirala/cross-k"&gt;https://github.com/zlatnaspirala/cross-k&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Objective:
&lt;/h2&gt;

&lt;p&gt;Create multiplatform target builds with real time net driver.&lt;br&gt;
Basic : 2D UI visual app creator. Future features player, networking, 3d/2d canvas based engine.&lt;br&gt;
Because html5 is excluded for now from this story maybe some real time networking makes fit for &lt;br&gt;
all platforms. &lt;br&gt;
In basic we can create server-client native application for any platform (desktops, android)&lt;br&gt;
This is the beginning of a beautiful friendship&lt;/p&gt;

&lt;p&gt;Youtube presentation:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=Ci8GNd3FDHw&amp;amp;ab_channel=javascriptfanatic"&gt;https://www.youtube.com/watch?v=Ci8GNd3FDHw&amp;amp;ab_channel=javascriptfanatic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Screen shot details box:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--irC5t-o1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51cou4cm5vavsqsmo7ut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--irC5t-o1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51cou4cm5vavsqsmo7ut.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After cloning this project only need to install python3, pip3and kivy 2.0 framework You need first time to create kivy_venv:&lt;/p&gt;

&lt;p&gt;Windows command line&lt;/p&gt;

&lt;p&gt;python3 -m c kivy_venv&lt;br&gt;
Activate env before run engine&lt;br&gt;
Windows command&lt;/p&gt;

&lt;p&gt;kivy_venv\Scripts\activate&lt;br&gt;
Bash command&lt;/p&gt;

&lt;p&gt;source kivy_venv/Scripts/activate&lt;br&gt;
Installation&lt;br&gt;
pip3 install kivy[full] kivy_examples&lt;br&gt;
pip3 install --upgrade pip wheel setuptools&lt;br&gt;
pip3 install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew --user&lt;br&gt;
pip3 install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew &lt;br&gt;
             --extra-index-url &lt;a href="https://kivy.org/downloads/packages/simple/"&gt;https://kivy.org/downloads/packages/simple/&lt;/a&gt;&lt;br&gt;
pip3 install kivy&lt;br&gt;
pip3 install kivy.deps.gstreamer&lt;br&gt;
pip3 install kivy.deps.angle&lt;br&gt;
pip3 install --upgrade pyinstaller&lt;br&gt;
pip3 install python-for-android&lt;/p&gt;

&lt;p&gt;cd submodules/&lt;br&gt;
docker build --tag=p4a --file Dockerfile .&lt;br&gt;
If you have problem with:&lt;/p&gt;

&lt;p&gt;pip3 ...&lt;br&gt;
Then use this format&lt;br&gt;
pip3.9 install ...&lt;br&gt;
or&lt;br&gt;
python3 -m pip install&lt;br&gt;
Run Engine:&lt;br&gt;
You can use it like this if have some paths problem kivy_venv/Scripts/python.exe.&lt;/p&gt;

&lt;p&gt;python main.py&lt;br&gt;
Package System&lt;br&gt;
[WINDOWS]&lt;/p&gt;

&lt;p&gt;Pack Application for windows10 with GUI command.&lt;/p&gt;

&lt;p&gt;Manual you can package whole engine not just application project.&lt;/p&gt;

&lt;p&gt;kivy_venv/Scripts/python.exe -m PyInstaller --onefile --name CROSSK_PROJECT1 --distpath packages/projectTest --workpath .cache/ main.py&lt;br&gt;
[ANDROID] WIP&lt;/p&gt;

&lt;p&gt;docker run \&lt;br&gt;
    --interactive \&lt;br&gt;
    --tty \&lt;br&gt;
    --volume "G:\web_server\xampp\htdocs\PRIVATE_SERVER\PYTHON\cross-k\cross-k\":/home/user/testapps \&lt;br&gt;
    p4a sh -c&lt;br&gt;
        '. venv/bin/activate \&lt;br&gt;
        &amp;amp;&amp;amp; cd testapps \&lt;br&gt;
        &amp;amp;&amp;amp; python setup_vispy.py apk \&lt;br&gt;
        --sdk-dir $ANDROID_SDK_HOME \&lt;br&gt;
        --ndk-dir $ANDROID_NDK_HOME'&lt;/p&gt;

&lt;p&gt;docker run --interactive --tty --volume "/G/web_server/xampp/htdocs/PRIVATE_SERVER/PYTHON/cross-k/cross-k/submodules/python-for-android/testapps":/home/user/testapps p4a sh -c ". venv/bin/activate &amp;amp;&amp;amp; cd testapps &amp;amp;&amp;amp; python setup_testapp_python3_sqlite_openssl.py apk --package=nikola.car.sdl2 --name='nidzasdl2' --version=0.5 --bootstrap=sdl2 --sdk-dir $ANDROID_SDK_HOME --ndk-dir $ANDROID_NDK_HOME "&lt;/p&gt;

&lt;p&gt;Docker:&lt;/p&gt;

&lt;p&gt;p4a apk python3 setup_testapp_python3_sqlite_openssl.py --package=nikola.car.sdl2 --name='nidzasdl2' --version=0.5 --bootstrap=sdl2 --sdk-dir=/usr/lib/android-sdk --ndk-dir=/home/user/android-ndk/android-ndk-r20&lt;/p&gt;

&lt;p&gt;/usr/lib/android-sdk&lt;br&gt;
/home/user/android-ndk/android-ndk-r20&lt;/p&gt;

&lt;p&gt;wget -c &lt;a href="https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip"&gt;https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip&lt;/a&gt; &lt;br&gt;
unzip android-ndk-r20-linux-x86_64.zip &lt;/p&gt;

&lt;p&gt;export ANDROIDSDK="/usr/lib/android-sdk"&lt;br&gt;
export ANDROIDNDK="/home/user/android-ndk/android-ndk-r20"&lt;br&gt;
export ANDROIDAPI="28"  # Target API version of your application&lt;br&gt;
export NDKAPI="20"  # Minimum supported API version of your application&lt;br&gt;
export ANDROIDNDKVER="r20"  # Version of the NDK you installed&lt;br&gt;
export PATH=/usr/lib/android-sdk/:$PATH&lt;br&gt;
export PATH=/usr/lib/android-sdk/cmdline-tools/3.0/bin/:$PATH&lt;br&gt;
source /etc/bash.bash&lt;br&gt;
source .bashrc&lt;/p&gt;

&lt;p&gt;sudo su&lt;/p&gt;

&lt;p&gt;docker cp C/Users/Nikola Lukic/Downloads/commandlinetools-linux.zip CONTAINER_ID:/usr/lib/android-sdk&lt;br&gt;
android tools still needed to install &lt;br&gt;
docker commit 3ecefc2ff45d  crossk/android:ver2&lt;br&gt;
STRUCTURE&lt;br&gt;
(non project files) =&amp;gt; Files from marked folder are not in active dependency of this software. (Auto generated) =&amp;gt; Usually dont edit dont use it (VisualCode/debugger) =&amp;gt; You can find help script for python debugger from MS Visual Code Editor.&lt;/p&gt;

&lt;p&gt;├── .cache/                        (Auto generated)&lt;br&gt;
├── .vscode/                       (VisualCode/debugger)&lt;br&gt;
├── components/                    (empty for now)&lt;br&gt;
├── demos/                         (not project files)&lt;br&gt;
├── main.py                        (Engine Instance)&lt;br&gt;
├── app.py                         (App Instance)&lt;br&gt;
├── engine/&lt;br&gt;
|   ├── assets/&lt;br&gt;
|   ├── common/&lt;br&gt;
|   |   └── assetsEditor.py&lt;br&gt;
|   |   └── assetsEditorOperation.py&lt;br&gt;
|   |   └── commons.py&lt;br&gt;
|   |   └── enginePackage.py&lt;br&gt;
|   |   └── modification.py&lt;br&gt;
|   |   └── operationBox.py&lt;br&gt;
|   |   └── operationButton.py&lt;br&gt;
|   |   └── operationLabel.py&lt;br&gt;
|   |   └── operationsPicture.py&lt;br&gt;
|   ├── editor/&lt;br&gt;
|   |   └── layout.py&lt;br&gt;
|   |   └── networking.py&lt;br&gt;
|   |   └── resources.py&lt;br&gt;
|   |   └── scripter.py            Future visual node sub editor,text script for now&lt;br&gt;
|   |   └── resourcesGUIContainer.py&lt;br&gt;
|   |   └── sceneGUIContainer.py&lt;br&gt;
|   ├── config.py                  (Engine editor config)&lt;br&gt;
|   ├── editor_main.py             Main Engine File&lt;br&gt;
|   ├── app_main.py                Main Final App File [Used for package proccess]&lt;br&gt;
|   ├── kivy_venv/                 (Auto generated - env libraries)&lt;br&gt;
|   ├── projects/                  (Auto generated - Project files)&lt;br&gt;
|   ├── shader-editor/             (non project files)&lt;br&gt;
[CROSSK-STATUS-LIST]&lt;br&gt;
ACTUAL VERSION [no release] BETA&lt;/p&gt;

&lt;p&gt;BETA VERSION [0.3.0] STATUS&lt;/p&gt;

&lt;p&gt;[EDITOR]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add option solution for dimension ref system&lt;br&gt;
(use pixels, percents or combine)  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add option solution for frameLayout and &lt;br&gt;
position hint also.&lt;br&gt;
(use pixels, percents or combine)   &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manage scene element&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Details box with save options&lt;/li&gt;
&lt;li&gt;SceneContainer to select and preview render elements
in left side of engine window -scroll added&lt;/li&gt;
&lt;li&gt;AssetsContainer to select and preview assets items
in left side of engine window -scroll added&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Add Element type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Button element&lt;/li&gt;
&lt;li&gt;Label element&lt;/li&gt;
&lt;li&gt;CheckBox element&lt;/li&gt;
&lt;li&gt;Picture Clickable&lt;/li&gt;
&lt;li&gt;Layouts (dinamic with props) element&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Layouts - Handle sub components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Layouts ( Details commands:&lt;br&gt;&lt;br&gt;
                  - Add button&lt;br&gt;&lt;br&gt;
                  - Add Label&lt;br&gt;&lt;br&gt;
                  - Add layout )&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CrossK Scripter, Basic script bind attacher for live (app) buttons.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[ASSETS EDITOR]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operation ( Type of Asset:
                      - imageResource,
                      - fontResource)&lt;/li&gt;
&lt;li&gt;OperationAdd&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[PACKAGE-SYSTEM]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package for windows                             [SUPPORTED]&lt;/li&gt;
&lt;li&gt;Package for Linux                               [SUPPORTED]&lt;/li&gt;
&lt;li&gt;Package for android                             [NOTESTED]&lt;/li&gt;
&lt;li&gt;Package for macOS                               [NOTESTED]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[PACKAGE-ANDROID]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test kivy solution                               [NOTESTED]&lt;/li&gt;
&lt;li&gt;Test canvas solution (if ti posible)             [NOTESTED]&lt;/li&gt;
&lt;li&gt;Test opengles2/3 in native canvas manir          [NOTESTED]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Android WIP&lt;br&gt;
Best choose Linux Ubuntu&lt;/p&gt;

&lt;p&gt;pip install python-for-android&lt;br&gt;
For windows users use docker&lt;/p&gt;

</description>
      <category>kivy</category>
      <category>visual</category>
      <category>tooling</category>
      <category>engine</category>
    </item>
    <item>
      <title>Vue/Typescript/Threejs project - search &amp; play youtube videos in 3d webGL open source</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Wed, 29 Jul 2020 07:43:45 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/vue-typescript-threejs-project-search-play-youtube-videos-in-3d-webgl-open-source-4idk</link>
      <guid>https://dev.to/zlatnaspirala/vue-typescript-threejs-project-search-play-youtube-videos-in-3d-webgl-open-source-4idk</guid>
      <description>&lt;p&gt;vue-ts-starter&lt;br&gt;
Project name: Vue project generator&lt;br&gt;
First feature: YouTube vs Threejs&lt;br&gt;
version 0.0.5&lt;br&gt;
Public access for VuleTube service:&lt;br&gt;
&lt;a href="https://maximumroulette.com:3000"&gt;https://maximumroulette.com:3000&lt;/a&gt;&lt;br&gt;
vuletube&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EkmqMVOQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/crpuhihlkd3etgnx4ezg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EkmqMVOQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/crpuhihlkd3etgnx4ezg.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Production use https node application for web server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  git clone https://github.com/zlatnaspirala/vue-typescript-starter
  npm i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Other good solution is node serve for instant start.&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm install -g serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  serve -s dist
  // or
  npm run serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Project details&lt;br&gt;
Features&lt;br&gt;
Note:&lt;/p&gt;

&lt;p&gt;0.0.x =&amp;gt; any changes&lt;br&gt;
  0.x.1 ... n =&amp;gt; any changes + updated present logic or new big feature.&lt;br&gt;
  x.1.1 ... n =&amp;gt; release git/build point version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version 0.0.2 [MASTER]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Getting response for youtube search.&lt;br&gt;
Call server part for saving videos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version 0.0.3 [MASTER]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add options switch-place for two main components&lt;br&gt;
Implement LocalStorageMemory class (For saving all user infly data - view options etc.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version 0.0.4 [MASTER]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save current (exist) options with localStorage and load on refresh.&lt;br&gt;
Every next options will be implemented with localStorage support.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version 0.0.5 [MASTER]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Added new server module : npm install --save image-downloader&lt;br&gt;
Prepare for search result preview in 3d. with raycast options for navigate. Add options for:&lt;br&gt;
save result number per page - pagination.&lt;br&gt;
show result in 3d&lt;br&gt;
version 0.1.1 [WIP NEXT]&lt;/p&gt;

&lt;p&gt;Adding paypal donate buttons&lt;br&gt;
Prevent raycast click event behind 3d plane video FIX@&lt;br&gt;
Adding progress for video duration.&lt;br&gt;
Adding webcam options&lt;br&gt;
Replace text with icons&lt;/p&gt;

&lt;p&gt;## Project structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── dist/  (This is auto generated)
├── node_modules/  (This is auto generated)
├── public/
|   ├── assets/
|   |   └── logo.png
|   ├── thumbnails/
|   ├── videos/
|   |   └── list.html
|   ├── bad.html
|   ├── favicon.ico
|   ├── index.html
├── server/
|   ├── node_modules/ (This is auto generated)
|   ├── package.json
|   ├── package-lock.json
|   ├── server-connector.js
├── src/
|   ├── components/
|   |   ├── youtube-3d/
|   |   |   ├── myYouTube.vue
|   |   |   └── webgl-player.vue
|   |   ├── myFooter.vue
|   |   ├── myHeader.vue
|   ├── App.vue
|   └── styles/
|   |   └── styles.scss
|   ├── App.vue
|   ├── main.ts
|   ├── error-instance.ts
|   ├── shims-tsx.d.ts
|   ├── shims-vue.d.ts
|   └── store.ts
├── .gitignore
├── README.md (This file)
├── tsconfig.json
├── package.json
├── package-lock.json (This is auto generated)
└── babel.config.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Components :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;myYouTube.vue Getting response for youtube search. Call server part for saving videos&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;webgl-player.vue Open opengles port view, look for video source saved to the maximumroulette:3000 I use quick solution from npm: &lt;a href="https://www.npmjs.com/package/youtube-dl"&gt;https://www.npmjs.com/package/youtube-dl&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Response for youtube api v3 call search.
  body: "{↵  "kind": "youtube#searchListResponse",↵  "etag""
  headers: {cache-control: "private", content-encoding: "gzip",
  content-length: "5512", content-type: "application/json; charset=UTF-8", date: "Sun, 05 Jul 2020 20:47:06 GMT", …}
  result: {
    kind: "youtube#searchListResponse",
    etag: "3nOm8AR0NU4TDlCxh0UCxk1KB38",
    nextPageToken: "CBkQAA", regionCode: "RS", pageInfo: {…}, …}
  status: 200
  statusText: null
Result property:
{
"kind": "youtube#searchResult",
"etag": "mlweRndBtBgAcVC-11ZrL0oI7ok",
"id": {
  "kind": "youtube#video",
  "videoId": "YPhJOC9-M_M"
},
"snippet": {
  "publishedAt": "2019-07-14T19:27:31Z",
  "channelId": "UCc1NtMtvoVzKnOtnai9LGsA",
  "title": "Create game engine - Visual typescript game engine",
  "description": "Clone or download from : https://github.com/zlatnaspirala/visual-ts-game-engine Next video\
    developing in live - adding multiplayer feature. Project : Visual ts ...",
  "thumbnails": {
    "default": {
      "url": "https://i.ytimg.com/vi/YPhJOC9-M_M/default.jpg", "width": 120, "height": 90
    },
    "medium": {
      "url": "https://i.ytimg.com/vi/YPhJOC9-M_M/mqdefault.jpg", "width": 320, "height": 180
    },
    "high": {
      "url": "https://i.ytimg.com/vi/YPhJOC9-M_M/hqdefault.jpg", "width": 480, "height": 360
    }
  },
  "channelTitle": "javascript fanatic",
  "liveBroadcastContent": "none",
  "publishTime": "2019-07-14T19:27:31Z"
  }
}

{
  etag: "3nOm8AR0NU4TDlCxh0UCxk1KB38"
  items:
      etag: "mlweRndBtBgAcVC-11ZrL0oI7ok"
      id: {kind: "youtube#video", videoId: "YPhJOC9-M_M"}
      kind: "youtube#searchResult"
      snippet: {publis
      kind: "youtube#searchListResponse"
      nextPageToken: "CBkQAA"
      pageInfo: {totalResults: 400229, resultsPerPage: 25}
      regionCode: "RS"
      }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;VueMaterial help&lt;br&gt;
 Notes:&lt;/p&gt;

&lt;p&gt;All other  attributes, such as multiple and accept, can be used on md-field.&lt;br&gt;
Icons used with &lt;a href="https://fontawesome.com/v4.7.0/icons/"&gt;https://fontawesome.com/v4.7.0/icons/&lt;/a&gt;&lt;br&gt;
eslint or any other cheker full strict only for proc build in dev status lint will pass more roles.&lt;/p&gt;

&lt;p&gt;Spiral position&lt;br&gt;
Not in use at the moment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  var count = 10;
  var radius = 32;
  for ( var i = 1, l = count; i &amp;lt;= l; i ++ ) {
    var phi = Math.acos( - 1 + ( 2 * i ) / l );
    var theta = Math.sqrt( l * Math.PI ) * phi;
    var mesh = new THREE.Mesh( geometry, material );
    mesh.position.setFromSphericalCoords( radius, phi, theta );
    mesh.lookAt( this.camera.position );
    this.scene.add( mesh );
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;YT Download module&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Download from: https://www.npmjs.com/package/youtube-dl&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Help links/public&lt;br&gt;
&lt;a href="https://vuematerial.io/themes/configuration"&gt;https://vuematerial.io/themes/configuration&lt;/a&gt; &lt;a href="https://github.com/google/google-api-javascript-client/blob/master/docs/samples.md#LoadinganAPIandMakingaRequest"&gt;https://github.com/google/google-api-javascript-client/blob/master/docs/samples.md#LoadinganAPIandMakingaRequest&lt;/a&gt; &lt;a href="https://developers.google.com/youtube/v3/docs/search/list?apix=true"&gt;https://developers.google.com/youtube/v3/docs/search/list?apix=true&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Direct link for dev server&lt;br&gt;
VueTube web DEV [WIP] service 2020&lt;br&gt;
&lt;a href="https://maximumroulette.com:3000"&gt;https://maximumroulette.com:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Credits:&lt;/p&gt;

&lt;p&gt;Used in my project:&lt;br&gt;
project structural/methodology&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vuejs.org/"&gt;https://vuejs.org/&lt;/a&gt;&lt;br&gt;
JavaScript 3D library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://threejs.org/"&gt;https://threejs.org/&lt;/a&gt;&lt;br&gt;
Download videos from youtube in node.js using youtube-dl.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/youtube-dl"&gt;https://www.npmjs.com/package/youtube-dl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download source code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zlatnaspirala/vue-typescript-starter"&gt;https://github.com/zlatnaspirala/vue-typescript-starter&lt;/a&gt;&lt;br&gt;
Star project and thank you for visit my content.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
