<?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.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>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>
    <item>
      <title>Kure small video chat service</title>
      <dc:creator>Nikola</dc:creator>
      <pubDate>Mon, 08 Jun 2020 22:25:04 +0000</pubDate>
      <link>https://dev.to/zlatnaspirala/kure-small-video-chat-service-o93</link>
      <guid>https://dev.to/zlatnaspirala/kure-small-video-chat-service-o93</guid>
      <description>&lt;p&gt;&lt;strong&gt;About Kure application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Application based on kurento project &amp;amp; openvidu project&lt;br&gt;
You can find origin source code and licence on: Licence page Kurento project page Openvidu project Openvidu tutorials project&lt;/p&gt;

&lt;p&gt;Main reason for KMS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WEBRTC VIDEOCONFERENCES
One-to-One, One-to-Many, Many-to-Many. Any combination you can think of is possible with OpenVidu.&lt;/li&gt;
&lt;li&gt;OPEN SOURCE
OpenVidu is an OpenSource project licensed under Apache License v2. Use it for free.&lt;/li&gt;
&lt;li&gt;MULTIPLATFORM
Chrome, Firefox, Safari, Opera, Edge, Android, iOS, desktop apps. All compatible with each other
I recommended everyone to use docker.
This project is commercial and i use it to run my own services.
Middleware server base on node.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Protocol http2 for node middleware server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation of session websocket based account system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(used from visual-ts game engine project)&lt;/p&gt;

&lt;p&gt;Kure Video Chat is commercial project but you can find code for &lt;code&gt;session account system&lt;/code&gt; from:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zlatnaspirala/visual-ts-game-engine/blob/master/server/rtc/connector.js"&gt;https://github.com/zlatnaspirala/visual-ts-game-engine/blob/master/server/rtc/connector.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zlatnaspirala/visual-ts-game-engine/blob/master/server/common/shared.js"&gt;https://github.com/zlatnaspirala/visual-ts-game-engine/blob/master/server/common/shared.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;KMS vs openvidu docker variant with nodejs middleware.&lt;br&gt;
Public web server for Kure service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maximumroulette.com:2020"&gt;https://maximumroulette.com:2020&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Websocket port: 3232&lt;/p&gt;

</description>
      <category>kurento</category>
      <category>videochat</category>
    </item>
  </channel>
</rss>
