Code a Virtual 3D Art Gallery – Three.js JavaScript Tutorial _ Code-a-Long

**Implementing Mouse Click Handling in 3D Art Gallery**

We are using JavaScript to implement mouse click handling in our 3D art gallery. The primary goal is to detect when the user clicks on any of the paintings in the scene and perform a desired action. To achieve this, we create a function called `onclick` that takes an array of paintings as arguments.

The function first accesses the `Ray Caster` object from the camera and calls its `set` method, passing the normalized mouse coordinates for x and y as well as the camera itself. The `requesters` intersection with objects method is then used to get an array of intersections between the current position and the paintings in the scene.

If this intersect array is not empty, it means that the user has clicked on a painting. In this case, we grab the first intersection which represents the closest painting that the user clicked on. We then perform our desired action, which in this example, is opening a new web page to our shop landing page.

To implement this, we add a condition to check if the intersect array is not empty. If it's not, we create a variable `painting` to access the first painting in the array and perform the desired actions. We log the clicked painting to the console for debugging purposes.

In the JavaScript code, we use the `const` keyword to declare the `painting` variable, which represents the first painting in the intersect array. We then access its properties, such as `title`, using the `user.data.info.title` syntax. This is where the user data object from the painting file comes into play.

We add a new property called `URL` to the user data object, which will be used to open the external page. In this example, we assume that the URL is already set in the user data object, but in reality, it would need to be dynamically generated or retrieved from an API.

To open the external page in a new tab, we use the `window.open()` method and pass the link as an argument. We can access the same link using the `user.data.info.link` property.

**Enabling Click Handling**

Before testing the click handling functionality, we need to enable it by calling the `onclick` function with the correct arguments. In this case, we call the `clickHandling` function from the main JavaScript file and pass `render`, `camera`, and `paintings` as arguments.

To test the click handling, we disable any existing locks on the screen to ensure that the event is not overridden by another application. We then simulate a mouse click on one of the paintings to see if the desired action is performed.

However, in this case, clicking anywhere on the screen does not trigger the `onclick` function, which suggests an issue with the implementation or the environment. Further investigation reveals that the normalization of the screen space using the 3JS library might be causing the problem.

To fix this, we adjust the script to set the normalized coordinates correctly, ensuring that the x-coordinate is between -1 and 1 and the y-coordinate is also between -1 and 1. After making this adjustment, the click handling functionality works as expected.

The final step is to log the clicked painting to the console to verify its correct identification and to confirm that the desired action has been taken when a painting is clicked. In this example, opening an external page in a new tab is performed when a painting is clicked.

"WEBVTTKind: captionsLanguage: enunlock the world of 3D web experiences with this beginner-friendly 3js tutorial you will learn how to create an interactive 3D art gallery to Showcase your portfolio in a dynamic engaging way this course will cover all you need to know about 3js fundamentals such as scene camera renderer geometry materials and more amelon created this course and he will provide you with Hands-On lessons on animation meshing user interaction and utilizing a gooey bugger for real-time configuration all designed to empower you to bring your Creative Visions to life on the web hello everyone in the next 8 hours we are diving into the world of 3js to craft an interactive 3D art gallery this is what we are going to build so usually I go in Windows plus air write CMD open on the terminal here in the terminal CD desktop so I will create my project in the desktop then MK deer this creates a folder in the desktop and the name of the project so Art Gallery simply okay we created the folder let's get into this folder CD Art Gallery okay and now let's open it in our vs code we usually use vs code is the best editor out there so code and Dot okay we are in the vs code we have this folder now we need to create some files that we need usually we need uh HTML file uh of course a CSS file for the styles and also the functionality that is the JS file with JavaScript okay uh if you don't know we are working with this project we will work with this with 3js okay 3js is a cross browser JavaScript library and application programming interface used to create and display animated 3D computer Graphics in a way web browser using webgl okay uh the source code is on GitHub it's open source so it's a very nice Library I really like it I am a fan of 3D usually I I used to work with unity Unity 3D in my opinion Unity is the best ever tool out there for me but I really like also 3js if you want to create Games Etc Unity is is like the best tool for me also unreal but I am a Unity Fanboy but if you want to work in a browser with 3D models or you know 3D programming for web applications 3js is the best choice there is also babylonjs it's also great and it's maintained from Microsoft but yeah I think 3js it's very uh easy I mean very easy it's like let's say easy compared to you know other Frameworks that has a very steep learning Cur but 3js if you know JavaScript it's very easy to get into if you are a JavaScript developer okay so no more talking let's create let's create first uh an HTML file okay we need an HTML file so index.html okay let's create the template so you just simply write the exclam uh I don't know in English but I think it's called like that okay so we have the template right let's create uh immediately the other files so we have the structure you know the structure of the project and so slowly we can build the project okay so the index HTML create one let's create a folder so it's better to keep the files on folders with a specific name so JS for example we have here the files uh JavaScript files that there might be many files or only one file one main file maybe we can create everything inside one file but we might need other files so let's create a folder JS let's create the CSS folder also oh it's created inside oh sorry come on delete permanently okay CSS folder okay let's also create the file so style. CSS okay and also a main JS file main.js all right so we have have here uh what is important and I think we can do it since the beginning we should import the module of 3js so we need a module uh by 3js you can go to Google and uh simply search 3js GitHub module or something like that and here you will see this is the Mr dup it's the maintainer and creator of 3js and you can download the file here if you are familiar with GitHub you already know if you're not familiar with GitHub uh here in the green button click the green button uh download the zip file and inside what we really need we don't need everything here actually so now it's uh it's not very light it's like there are many files here many files but what we need is inside inside the build okay inside the build folder so after you download it I already have it that's why I'm I don't have a problem I already have it if you don't want to go through this I will I will post this project the whole project on my GitHub so you can simply go and copy the file in my GitHub if you want to know this because maybe you will need it with other projects that you will create yourself so it's good to know we you will do this every every time you will need this inside the build folder you will need this three.js file or 3. MJS it's a mini ified version so the minified version or the 3js this is for modules it's like you if you are familiar with es6 Etc it's like built uh but for now you you just need this one 3js or the minified version I will go with the this file 3js okay so here code download I have it here so I go and will copy it so three file let me go to this folder so reveal in file explorer I will put it here all right I am not using the minified version but the minified is lighter anyway this is just a propose of a tutorial let's go back so we have the 3js here okay let's create if you want to take a look inside maybe it's you know it has classes Etc about every everything you see is pretty pretty big it's there are there are a lot of classes methods functions and every everything about 3js that we will need to to to create and do 3D programming okay but let's leave this for the advanced guys so let's go to our HTML files let's change the title First Art Gallery okay maybe let's add the CSS file so let's edit now and uh we will need it later so uh here about add link okay Styles sheet so HRA it will be in this folder CSS so CSS style CSS okay great so let's build the file maybe first let's open this in our browser so go live here go live go live or click the right and then open with live server or the shortcut alt plus L all alt plus o okay so here is our project it's here on this uh address in our local we don't see anything because we don't have anything so let's create some files here so we can see what we will need we will need you know the we will need the background the main background that we'll have I don't know we have the scene of our project then another it will be a div so then another div inside will be a main container maybe uh then an H1 we will make like uh we will make like a menu when we first click uh our project it will open up a menu with some information you know the title Art Gallery Etc and maybe some instructions or you know it's up to you actually it's up to you but let's make a very easy one a very simple one so let's create a main div and let's give it a class name of background or background menu so if you want to be if you want to have some shortcuts to be a good developer if you don't know maybe many of you already know these things you know so don't bear with me maybe some others are beginners and they would like to know these shortcuts to be fast and you know Pro tips so if you want to create a div not going to div and then give it a class you know so div then go and class and then add the class name menu Etc there are some Pro tips so you can be quicker and faster so dot and the name of the class the name of the class will be for example background menu so do background menu enter this is the EMT abbreviation and you see it's quick and it's fast it's a nice shortcut or it's my oh my God it's myal okay so again you will make you will create another div with another class the same thing so dot and put the name of the class it will create a div with a class name ready okay so go with these things and you are quicker or if you don't want the class but you want maybe an ID so this uh sign of the ID and then put the the name of the ID that you want and enter it will create the div with ID menu okay what we need and then inside this menu we will inside we we will add the title uh maybe we will add an image okay we want a nice image they want to show this Gallery before and maybe click button like uh explore explore the gallery or enter the gallery uh Etc so we have menu div let's add the yeah let's add an an image let's create a div with uh image container so ID and uh image container okay and inside let's set an image okay this will be the source I will let the image now and you know just menu pick doesn't matter okay uh let's add the the picture yeah let's set the picture oh this is my pictures don't where do I have those pictures I have some okay I want to add this the stay night that's why maybe create a folder for this yeah let's create a folder for this image let's set it inside okay let's set the source so image ster night great let's change the AL here night good okay we see something here in our browser so what else what else we need uh yeah we need the title you know the menu we need the title so a title and description Maybe yeah title and the description okay so title image uh description what else we may need we may need like uh or maybe let's keep it simple yeah let's keep it simple for now let's set maybe an image a title and uh a description okay so this is for the title and uh yeah let's keep it for now ID this is will be the content the content and yeah and each one that will be hard color okay and uh it will also have the description and uh inside let's create a P A P tag with a description this is an interactive uh 3D gallery okay uh description maybe some other description if you want made with love and 3js and 3js okay what else yeah we see something here what else what else uh yeah maybe we will need like some instructions how to move what we will do etc etc right okay so instructions maybe bet always instructions here B tag again move left or right it doesn't matter Arrow so arrows and look around look around with mouse yeah uh let's set maybe a bom to start to play it's like just play Enter G okay let's give an ID to this one play button okay okay it is something also also we need the scripts okay we also need the scripts we will add here the 3js script so and you have you should keep in mind something here a the script and here in the script SRC we will put our 3js okay you should keep in mind always always uh add the 3js script before everything else okay so above all at the top you add this script of 3js and Below you add the MJS file etc etc okay so like this it will be uh JS you don't need the dot and you know so simply JS no main JS it's threejs so JS 3js okay this is it another script okay you see how I cop it you can put you can press shift alt and the down arrow and you copy like this okay so shift alt and the arrow down let's change this one this is for the main Js Js M Jaz okay uh so we have pretty much much everything here for the HTML maybe we should add the Styles and then we can work for the real project with JavaScript and create everything set up 3js set up the canvas the camera render objects and you will see yourself everything else okay so styles let's set some Styles maybe if you don't want to follow along about Styles it this really doesn't interest you the HTML ex you can look uh the final result or just grab and copy and paste from my GitHub so just don't don't worry or just forward I will add some Styles here there is nothing to really explain so we'll add this style so why is Skip okay there are also some shortcuts shortcuts for for the CSS if you don't know those are our beginners so for example I want the width 100% so not going width and then 100 I can simply write uh W and 100 enter and very very quick the same age 100 quickly for the font size F uh s and the 12 size you have the font style or font or sorry it's font style I need the font size okay whatever but yeah there are this shortcuts also called color let's give it like I have some this is the result of the CSS style you can copy this in my GitHub so let's leave the CSS and uh let's open our jsjs file and here it starts the 3js project so we want to click this enter the gallery after clicking it U the menu will hidden and we will see this 3D object where we can interact and move around we will put a big box there you know we will put M the floor we will put the walls and then create create you know the paintings that will be some some planes and we can put there attach uh a texter and let's see together but first of all we need some Main and important things when we create a 3js project that pretty much you will do a every single time these are the main Concepts and the main things you would need in a 3js project so everything you will work here in this file you will work by using this file here 3js that inside it has everything and if you want to check it yourself you can console log this big object because this is an object it's a very big object if you want you can console log it and see yourself and inside uh the three so uppercase three oh sorry sorry okay three let's check let's conso log f r three is now defined okay let's see let's see here I think it's a problem here CJs 3js s CJs M JS okay guys I stopped the video for a moment I went and I drank some water I changed my t-shirt I have my piggy blinders hat and got myself a cup of coffee uh no I don't drink coffee I take tea my dear like the song by Sting actually it's Jin sank not a coffee uh for my brain my small brain okay so this uh we had this error and it's it's just a stupid error actually it's usually when you see this error like uh you cannot get the 3js and because execute because it's my typ ET ET this just most probably we just uh mistyped here the source uh what's happened here I don't on tell script okay so it's just here the problem maybe we uh have a wrong path or mistype or maybe you are uh directing a path that it's not a JS script but it's like a CSS or Json or etc for example I just make this stupid errors sometimes so I didn't see that uh 3js is inside the JS folder and I thought is inside but not it's not inside it's outside as you can see so let's put it inside the JS folder because you see the path JS 3js okay it's inside it should uh work now and the should okay it's gone is gone U I was showing you before these three object let's give it a name okay let's take a look here console log you see three object here and this is very very big object it has like everything inside you know everything that we might need to work you see if I go and click on any of these you there are a lot of things uh inside of that okay so the three Library this file that we imported uh contains most most of the classes and properties that usually we might need on a classic project with 3js okay but but sometimes not every class that we might need is inside of this but we will talk about it maybe later when we will go through that problem okay because sometimes we need some other classes that are not inside this three and we should import it from another source okay but for now let's leave it so comment this one so guys we have the HTML file okay here we have like the Styles you can copy the CSS Styles if uh just don't worry about that just copy and paste the Styles uh we are not here to learn CSS but we are here to to do something with 3js and 3D okay so we have HTML we have the Styles now we want to add the interactivity the functionality with JavaScript or more exactly with 3js library and uh where to start where to start we will start by creating the canvas and then we will add a camera like in a movie scene okay because the canvas there is the scene we will need a camera like in a movie scene and then we will need a renderer so we will create the renderer to render the scene and the camera uh we may have have lights uh shadows and everything also in our scene we want to add the 3D models okay so our Gallery uh cubes uh and every kind of shapes that 3js has the possibility to to work with with with those geometries okay so first of all the first thing let's create the scene the most important thing and the first thing we should do create the scene okay so for that we just normally uh we just create a variable with the with the S okay and just save it there there are different methods to work here we can just work by creating the variables the functions uh Etc or we can create a an object and put everything inside this object okay it's like replicating the name space in C okay if someone of you uh is using C especially with game development you create like a namespace uh JavaScript doesn't have an mpace it's something that it's called G object okay where you put all your variables functions that then are methods Etc okay but let's keep it simple because I think we can do everything inside one single file in inside this main JS okay so we are not going through that you know pattern of object oriented Etc with objects just we can simply create so let scene or const SC because the scene usually you will not change it so it's a constant so const scene equal and here the keyword new to create a new scene this is you have to be familiar with objectoriented programming because you have classes and then you instantiate a new object with the properties of the the class so in this case we are just keep it simple for this kind of explanations new think about it just a new a new thing that we are creating okay with some properties that it has uh uh with itself in this case we are creating a new scene new let's call three okay and then with that oh sorry it's just my sorry new three okay and then with that operator oh my God why is this calling three and then SC with that operator we access uh the properties inside this this this class the the main class of three it may have other classes it may have you know uh functions methods properties and everything else okay so three. sin and parenthesis and that's it this is our scene let's put some comments I will let some comments during the the tutorial so when you get the code uh on GitHub you also have it commented so if you forget or you know it's just for the beginners is easier so create the scene this one what else as we said we need the camera so let's create a new camera like in a movie set you know we have the scene imagine imagine this scene to to to see this scene we need a camera to to to look and because when we render it will be through uh you know the eye of our camera okay so the same thing as we did with the the the Sim to to create a new a new camera we simply go by just const camera because it will be again a constant so const camera and with the specific class from three library that it's called perspective camera and I will explain it now okay so const camera equal it so again new and again three from the three Library we are accessing this three here this time we are accessing perspective camera okay and it accepts some parameters that I will explain now but con camera new three perspective camera the camera uh actually is not uh visible we cannot see this camera it's more like a a point of view okay so when we will do the render later of our Scene It will be from this point of view so from the camera's point of view we will render the scene of course like in a movie scene there are different types of camera and maybe we will talk about it later if we will need it not for now for now we will simply use uh this one the perspective camera it's like the perspective it's like making close objects look more prominent than the than the far objects the objects that are far okay so that's it to create you use this one one uh using this class perspective camera there are two main parameters that we need to provide inside there is the field of view and there is the aspect ratio I think you may know what the aspect ratio is it's like width divide by height okay width divide height you sa the the aspect ratio the field of view is uh how large our vision angle is so for instance if we use a very large angle we will be able to see in every direction at once but it will be with much Distortion okay because there result will be drawn in small rectangle but okay leave it for now if we use a small angle things will look zoomed in so the field of view is uh expressed in degrees and uh it corresponds to to the vertical Vision angle so here for instance we will give this parameters so 75 okay and this is the field of view it's like you know what I found that it's it's it's it's the correct let's say but you can play with this depending on the project so the the field of view and we also said a few moments ago we have the aspect ratio so the aspect ratio is width divide height in this case uh what we are dividing here the width of what the the width of the the the canas that we have the same so in this case we want it we don't want to to to put sizes okay we we will get the width of the window so the width of the whole window divide by the width the height of the whole window so we keep that ratio but using the window object that is the uh the window object of of the browser okay so window Dot inner width if you click the dot it you will show you know the properties divide by window do inner height okay and that's it a comment here so you have it clear uh aspect ratio okay then you as a third parameter and other parameters you can also add if you want depending on the project but this is for example 0.1 it's for the near clipping plane and also the far that I can put here 1,000 okay far and near and that's it for the camera that's it for the camera we don't see anything because we don't have anything in our scene we added the cam because the camera is not visible but anyway uh we created the camera but we always need when we create an object or when we create something in our canvas we need to add this to our scene so for that we have scene. ADD okay and as a parameter we add the camera this okay let's put some comments here s camera so we divided some kind categories if you want also to search and you easier okay we have the camera uh there is something that uh we you should not forget you should not forget for example if we have something in our scene we we cannot see it because we the camera when you create the camera by default the camera is in you know it's it's in the zero axis so we cannot see it it's like the camera is it's it's near the the the renderer so to to to make it possible to to look at the things we need to pull it back a little okay so the position of the camera in the Z axis will we will pull it back to to be able to to to see it's not a problem now because we don't have anything but it will be an issue let later so camera. position so we get the position property and then Z in the Z axis and a number five for example okay and this move the camera back five units good and this is done what's the next step the next step is the renderer we need a renderer also the canvas there are usually two ways someone will create a canvas here create a canas okay and then uh this canvas then access uh the canvas with a property like document that gets element by ID or by class you give you give a class or ID to to the canvas here in the HTML and access that and save it in a variable or you can simply create the renderer as we will do now without uh creating the canvas there and access it with document get element by ID okay so let's go for it and let's explain some basic things about the the renderer we will ask the renderer to render our scene from the camera point of view as we mentioned before and the result will be drawn into the conas okay so we mentioned that we can create the canvas by ourselves or let the renderer generated and then add it to our page so to our document uh body HTML to create the renderer we use the web GL renderer class as we did before with perspective camera class uh this time we will use the webgl render class with one parameter and that one parameter is an object you will see now render letter const render oh no always new three and we mentioned we will use the webg renderer class okay so to create the renderer we use this class webgl renderer okay and it accepts one parameter that it's an object okay and that's it let's just just just this one uh if we created the canvas here as we said before we will pass the canvas inside the renderer okay or let the renderer create that commer okay in this case in this case I didn't create a canvas in our HTML so I'm just leaving like that with the empty object inside this accept some other properties for example like ATI Alias okay I will explain uh what it is and this is for antialias means for smooth aging for the geometrist it will give like Smooth edges later when we we will let some geometries okay so we have the scene we have the camera and we have the renderer but we are not finished with the renderer uh we just created a new instance but we will set the size of the renderer okay so to set the size render do set size and again for the aspect ratio we will use window. inner width and uh window inner height so we will give this two parameters as the the size to set the size it sets the size of the render in this case the size will be the width of the window and the height of the window okay I hope it's clear window. uh inner width and window that inner height okay perfect we set the size of the render you can also add a B background color for the render for the canvas you can do it now or you can do it later doesn't matter but yeah since we are here we can give like a white simple and um the property to to to change the the color is set clear color it's not very intuitive but anyway and there are some ways to to change this to give a color you can give it like with quotes like blue red Etc or hexad decimal and you know you know those things so let's give it zero X and f f f f f is just for the white one and this is the background color and this is done the last thing you should not forget as we mentioned before we will add this renderer to our HTML for that doent body dot a pen child okay and inside renderer uh render yes render dot Dom element D element okay and that's it let's add a comment here so add the render to our HTML and this is done what else we can do we are still not seeing anything because we don't have geometries we don't have anything in our scene so our movie scene has no Act has no nothing it's like empty we only have the camera and we are looking to an empty SC we can also add the lights let there be light okay we can add like spotlights ambient lights all these lights have some properties like uh one has the property it lights the scene uh as a sun another one has some spotlights or Point lights we have different lights uh the lights we can create a whole uh new tutorial only about lights and shadows it's very interesting actually but for this tutorial we need just one or two simple lights two to to light the same lights let there be light one light that we mentioned it is the the ambient light the ambient light is like a soft light but that lights everything all the objects in the same but equally okay so let ambient light equal again I think now you are used to it new new keyword again three colum three ambient light uh why it's not suggesting me this I think it should suggest me the keyword normally but anyway we give a a color to the light it's like zero in this case just 0 1 0 one Z 1 Z okay also 1.0 this is for the color the first parameter for intensity okay again you also have some other parameters like distance and Decay but we are not using it if you just want to distance and okay but yeah okay so we have our ambient light also we can as we did with the camera we can give this light a position where we want to to to to put this this this where we want to put to put this ambient light in this case uh we can put it in the position of the camera where is the camera we want that light the camera moves it update lights with the position of the camera okay so ambient light our variable do position I think you guessed it position uh equal in this case camera. position okay and that's it again some comments light follows camera on Instagram okay so lights follows camera and uh I think many of you didn't forget that when we create something in our scene we should not forget to add this things to our scene with the with the add property so same. add inside ambient light okay and the light is created we can add not only the ambient light uh we also have some we have different lights but we can add at least another one the directional light and the directional light is a light source that act acts like the sun like you know in the in the real life it TS like the sun that it illuminates all objects in the scene equally you know from specific Direction okay so the directional light it it's it's like the sun and it it shines through and lights in a specific direction that we we are using it okay so let uh let's call it sun sunlight again new you are getting used to it okay so the more you practice the more you just get also in in in intuitive way okay even if you have not clear the the objectoriented programming pattern so you just you just get it I'm creating something new here and you know it's the new keyword so new again three accessing the three library and uh here directional light again we give it some color and intensity one two 3 four five and intensity 1.0 color intensity and we are done with the lights but of course you didn't forget again that we will always add this objects this things in our scene okay so again sin. uh sunlight now it's done we can also give some position since we said that this is a directional light we can give some position to it in this case since it's a a sum we will give a position in the Y AIS okay so it's like like this up and down like the sun it's like we give it a direction in this axis the y axis uh we will do it before adding it so sunlight. position you you see that it's very intuitive it's like not saying easy but you you you you can get through it if you know JavaScript it's that's why I like 3js it's intuitive it's it's it's a nice Library so sunlight do positiony in the y axis let's uh give it 15 so we have seen with camera we have the renderer added to our HTML and we have the lights in the end uh we want we want to to to to add the scene and the camera to to the render we need a render because the render is like the screenshot okay for the screenshot we need the camera and the SC that we are taking that screenshot okay so camera and scene that we are taking that screenshot like a screenshot so we need the render and to get the render we access the renderer variable that we created here above this one so render and for this renderer do render yeah it's a wordplay uh with the parameters same and camera because as we said to take the render to take that screenshot we need the camera and the scene that we are we are screenshotting okay uh something things to remember maybe if you don't see nothing after you create objects in the scene you we you should take in mind that uh you should specify the position of the objects or the position of our camera so we should not forget the camera it should be like pulled back a little so we can see things because if not out it's like I I I I go near the the the the camera of my laptop so I cannot see anything or reading the book it's like going like this so of course I canot see anything so I just need to put my eyes my field of view a little bit back so pulling back later when we will create the the objects you should also keep in mind to see the position of the objects if you are not seen anything render in the scene okay so we need to move things uh many times with 3js and that's it for now that's it for the main things the the main concepts of of of the scene of the canvas of 3js now we are going to do add some objects and we want to see something because we still don't see something this is just HTML it doesn't have nothing to do with the canas it has nothing to do with the three 3D World and 3js okay so we we created this lines of code oh that's why uh oh look look look I didn't see this maybe this was the reason I Your Parts was like the it's the old syntax of node but uh I don't need to import it if we use the server if we use webpac and express sometimes you need to import the three like import three from three it's like in react if you are used like you import a module that's why I was talking about modules uh before so if you use use a server Etc we will use it maybe in another project usually you import this three Library here the whole thing it's like import Asterix S3 from three like import everything from three but not in this case we just have it here in the scripts okay we are pointing to this path and we are just simply using it okay so we want to add some objects right we want to see something so like all our effort means something because now we don't need we we are not seeing anything but let me drink a little bit of some Gin sck uh also my cup are made of you know art this is like paintings I have a collection with different paintings this one is OS M okay I have like many of this with different paintings and pieces of art anyways so let's go for this object for the objects it's usually like we other 3D programming tools usually you create a cube you know the basic one the basic geometry we love the cubes we always start with a cube if we use um any other 3D software you know that you always start with a cube or you always start by deleting the cube the poor default Cube for example in blender those who use blender or work with blender they know that they open the program and the first thing they delete the the poor default Cube okay so we will create a cube just to see because later this Cube will be a box for our Gallery but since we are here for the beginners we need to explain a bit things step by step so bear with me please and also if you think that my English sucks at times I know it's not my native language and you know I can speak well at times you know but when you are live and explaining something technical it's you know you may have some problems so please uh understand this I know it can be frustrating maybe the accent or you know when someone doesn't speak very well their native language but okay anyway let's create this this this geometry uh yeah in the end here let geometry you see guys that now I see this I was wondering why I was not seeing any suggestion it was weird for me I added that line of code I don't know why I just it was the shortcuts I should delete some shortcuts actually sometimes they are a good thing sometimes they confuse you sometimes you don't even know that you created a line but you created it by by your shortcut or like GitHub copilot it it is great many times but sometimes if you don't know what you're are doing or you know just clicking you can add some line of code and get confused so first of all to create a 3D object what we do we create a geometry and we create a material then we create a mesh and we add this geometry and material inside this mesh seems confusing don't worry it's not it's uh pretty basic concept that the moment that you write it yourself you will just get it if not the first time just the second time it's I I will assure you that you will get it and it will become a second nature to you so let geometry again you know it now without my help new three and then uh do what I added something new you see that I added this I don't need this uh geometry new three for the geometry we need a class that is called box geometry box geometry and it accept some parameters uh for the three axis x y z it's like you give the size of it one one one simple one a small box box geometry is the shape of the object so we have the shape we need the class mesh basic material and uh the material is nothing else than the color so inside to add the color we we put the curly brackets the an object and inside this object we add properties in this case the property is color uh this is the color of of of of of it and in the end we create a mesh again new uh new three uh mesh as the name suggests and inside this mesh we put two parameters geometry and material geometry and material this creates the object okay great so we have it uh I think you know now what we should do right you know I'm sure you know we will add this Mash to a scene scene. add Mash this MH has the material and the geometry so this match is basically the object uh we can try and test it but I want to to to maybe explain maybe explain some basic concepts here so to to to reflect again what we did a vis visible object um like a cube to create it we need to create uh this type of object named mesh okay and mesh what is mesh it's uh simply a combination of the geometry okay and the the material the geometry is the shape I've added the comment here and the material is how it looks the color in this case but later we will add you know texter uh there are some other things but it it's how it looks the color in this in this case so you start with this geometry that is the Box geometry class okay that has three parameters that corresponds to the size the size of the Box the geometry okay uh for the material for the material we use the class mesh basic material uh it has one parameter and this parameter is an object okay containing all the options so the class mesh basic material with one uh parameter that is an object with all the options inside we have the property color so then I think you might know that to specify a color in 3js or in in JavaScript uh we can add hexad decimal uh number uh we can we can add the simple string like uh you know we can add it like this or uh as a string uh to to to to Ed it as a string we sorry we had the sign how is it called this sign I totally forgot English you know the ID sign anyway okay so there are these different ways to to or you can simply call it red like this okay for further information you you you get it in the internet so the final uh the final thing is the mesh so to create the final mesh we use the mesh class this one that we send inside as a parameters the geometry and the material okay and that's it in the end you add it to the scene let's see if we have any errors because yeah Art Gallery yeah I sorry it's the the the audio three has already been yeah of course of course that main JS has already been declared okay again this one that I sorry guys for this let's see okay 3. sin is not a Constructor having errors is normal you know it right see that's in yes looks okay okay so this sors is just a small back insignificant because it's just a typo it's not scene but seen uppercase okay so let's check it's normal I will not cut and edit these videos I will leave this mistakes and errors so yeah you maybe you you can learn from from this errors so I will not edit you know and cut the the parts of the video where I make mistakes oh okay we have another error uh what's this one cannot read properties of undefined render why let's check and Define render render render render render oh why I have this three here it is not needed so it's just renderer do render without three I don't know I have no idea why I wrote that but okay let's check okay finally no more errors uh it's good to know that we don't have errors but uh we want to see the object that we created right we created uh where is it we created here where is it okay we created the cube so we want to see that Cube so geometry and material added to a mesh as parameters to create this Cube so maybe here instead of mesh instead of mesh uh let's call it Q it's yeah it's let's call it Cube so this is the cube created with MH that accepts geometry and material but we don't see it we have just this uh HTML element we have no Cube but uh actually the cube should be behind this element because the canvas is behind this so we are covering it I think so let's hide it let's hide the whole element inside the body and we should see it now oops we don't see it uh let's check if any errors no errors no bugs but we don't see the cube why okay guys I am not uh cutting and editing this Parts uh where I have some some bugs so yeah let's find it together where is this problem I think it's it looks okay in correct so we have the geometry new three box geometry we give the size of the geometry okay this is correct we have the material we create a new mesh basic material inside an object with this property of color and this is also correct I don't see anything any typo but if we had a typo we would have an error here we don't have any error so this is like those cases that you have a problem but you don't have you know an error so it's like a hidden bug okay and yeah we shoot the bug and find it if we can I don't know guys if you see something wrong here I don't see it Cube It's a new mesh with geometry and material okay this is also correct and we add the cube to our scene we render it with scene and Camera this is correct guys this is correct let's see maybe the camera we pulled it back the camera uh the problem that we talk we talked about so let's check the position of the caram yeah yes here we move the camera back of five units so we should be able to see see it it's not this where is the problem render is okay the camera the camera the position of the cube did we move the cube the position no we didn't perspective field of view oh oh oh I got it I got it I got it okay that's why okay that's why you see here the perspective camera I told you that we need the two main parameters the field of view and the aspect ratio so we have the field of view we have the the aspect ratio and then I I I said that we can add the two other parameters for near and far okay but this one here I have no idea what it's doing there this zero so it's like it's like the third parameter it's like this is the near okay and this is the far so it's zero so yeah I I think this should be this is the buck okay so we have one for uh 0.1 for the near and 1,000 for for far so it was like a third parameter I I don't know let's check let's check should be okay perspective field and com pull it back yes let's check okay great we see it our small cube our little cute cute Cube okay it was like somehow hidden we okay so we have this object guys and we created it uh maybe we can make a small animation okay of it we can make a small animation and this is the yeah this is the the time to talk about the animations what are the animations yeah you know what are the animations but what are the animations in 3js and the case is that that we we do here so let's do something and let's explain it uh a bit okay so we are here for the animation actually we need to create the render this one here uh we need to create a function like a loop and this Loop will make possible to to to show this animation so for each frame I will explain it now in detail so we need the we need a function first so let's call it uh let render Loop or something like that okay so I will explain it like in detail because this is a cool thing it's something you know it's uh nice to to to to learn and to and to to to play with it maybe so a function render Loop function and then okay uh first let's put this inside to move this hold line you can uh press alt and the arrow the error up and down okay alt and error up and down just another shortcut uh okay we don't have a parenthesis here okay yeah I'm making many mistakes today uh so about the animations what we want I want to to to to rotate this this this Cube and to rotate this Cube uh I need to change the position of the cube right so this one here and to change the position we will change uh sorry not the position in this case because we will change the rotation sorry so the position we we moved uh before uh the camera Etc but in this case we need to to change the rotation so Cube Dot rotation okay uh rotation. X in the xaxis equal cube. rotation do X plus uh let's give it like a very uh very slow motion to rotate so it should be okay like 0.01 okay let's do the same for the Y AIS okay I cop it here and let's change only the y y here and Y here okay so this is what we need to rotate the cube in the in the X and in the Y AIS but if we check now we will see that nothing happened uh let's see this error no error but okay we need to call this yeah we need to call this render Loop let's call it only render okay so rotation and render as the see in the camera okay now we are back but again we don't see the the rotation we don't see any change as you can see it's it's it's the same why because we need something else we need something else and I want to explain uh something uh at this point so about the the animations the the animations when we use 3js uh they work like you have uh the idea of the stop motion yeah that's it uh we move the object and then we do a render and then again we move the object something more and we do another render Etc and so on the more we move the objects in the scene between these renders the faster they will appear to move okay yeah it's seems a little bit complicated like explaining it but the idea is the screen we are looking uh runs at a specific frequency okay so we call that uh a frame rate and you have heard about the frame rate I'm sure the frame rate mostly on on the screen but uh it depends on the screen and the computer itself has some limitations okay most screens run at 60 frames per second okay some screens can run much faster you know it depends on the computer some computers are faster some are slower and so on and when the computer has uh these difficulties processing uh things it will run of course more slowly uh in our case uh for the animations we want to execute uh a function this function here the render function that will move these objects and do the render on each frame but regardless of the frame rate so regardless of the frame rate that one computer has it you know regardless of it we want this function to to to do the render on each frame in JavaScript not only 3js but in JavaScript uh the way of doing this is by using uh request animation frame we can search for it together request animation frame okay is from the window object okay this one from MDM window. request animation frame uh the window request animation frame method tells the browser that you wish to perform an animation and request that the browser calls a specified function that we talked about to update an animation before the next repaint the method takes a call back as an argument to be invoked before the repaint okay let's leave for now the documents you have it here you can read it uh more in depth but let's do it because things uh you can understand things only by doing it and by a practical example so let's set this request animation frame that uh we we we saw so request animation frame and we pass here as an argument the function itself the render okay let's let's see now okay you see you see we now have this animation a small one we can change the speed here of course but yes we did it we have this animation thanks to this request animation frame okay and uh this is um it's simple uh here we can refactor a little bit our code instead of this we can you know just a shortcut another shortcut we we like shortcuts you just delete this and add a plus like this is here plus and delete this one it's the same thing okay it's the same thing so it's like saying uh plus equal it's like saying Cube rotation. x equal Cube rotation. X plus uh the number so it's the same thing let's check okay yeah nothing changed it's cleaner so we also made the animation what else we can do now uh I think we can add the movement so we can move this this little guy here our Cube we can move it you know at the controls left right up and down okay it would be cool to to to learn also this let's find a way a place here and uh let's set this one uh control controls okay and here we we also need to to explain some some other things but of course for beginners for those of you you can just keep this Parts those who are Advanced and just are interested in in seeing the final result you know the advanced things about to create the the the art gallery but for the beginners uh stay with me so to add the the controls uh what we what we will do we need to press a key of course uh the errors on our keyboard when we press the left uh Arrow we want to move to to the left left we press the right arrow we want to move to the right or not only the errors but yeah uh in most cases when we play a game we move with a D and W it's the same thing uh for this uh we need an event listener those of you that know JavaScript of course they know what an event listener is uh for those that don't know you maybe should check Google event listeners and learn about it a little bit but we will make things very simple here and even if you don't know you will understand it the moment that I will write it down okay so yeah I think you will understand it just by looking at the code and this is the the thing that we need to to to to always do write a code that it's very readable so let's add this event listener that when we press the keys uh it will listen to to this keys and then we'll make you know an action uh comment controls so in this case uh event listener when the when we press the keys we press the G okay uh we will create also this event listener with a function I will explain it in a bit so document. add event listener okay parenthesis it accepts as you can read here listener document event it will accept the kind of uh event it is a key down okay it is a key down and a function as a second parameter and this function we will create it to make possible you know to register this key press Etc let's call it on key usually when we create this kind of function we we call it on and the name of you know the action or the function that we want to do so on down always C case uh it has it has three parameters so yeah the key down the type key down listener uh also the function and uh options that is a bullan yeah let's leave it false the options okay so we have this event listener Kida let's create this function here on kidal function uh when a key is pressed execute this function okay function an okay a parenthesis it accepts a parameter that is the event if you want to to to to know more in depth about uh event listeners go and check mdn or the other resources so we have an event here as a parameter and this event uh will make us possible to access you know the event which we are triggering in this case our keys when we press the keys for this let's create a because we need to to to get what keys are we pressing how do we know we want to know uh from the code that this Keys have every key has a code in JavaScript okay so let's create a variable first uh key code let's call it key code and this variable key code will be event this one that we are accessing that which what is this this is to make possible to get the codes of each key let's search Google for these codes because I don't know I don't remember I cannot remember so key code tables yeah okay yeah I have clicked before for uh here we have all the key codes so as you as you can see enter is 13 uh shift uh Etc okay we need this one the errors so 37 38 39 and 40 so we need this we want to move the cube or the camera uh left and right so so we need this one these are the codes that uh do the work for us so we saved it in a variable evan. ttch and here we need the ni statement to to make possible to you know to get this the first one the key code which one uh 30 30 30 37 and 39 okay so 37 39 the right and the left the right is uh 30 39 right arrow okay let's uh make an if statement if key code this one here so if evan. which and this uh gets the code of all the keys okay so if key code equal 37 what's 37 was right or yeah it was left okay or let's start from the right if key code equal 39 so if the key is the the right arrow what we want to do we want to to to change the position of the cube or we can do another thing we can change the position of the camera we move the camera because when we will have the the player the player when we will enter the gallery inside uh we will not have a cube but actually we will uh like we have a a first person uh player that will enter the gallery and it will move around you know so for that we can use the camera so as a camera we can go like a PO view so we can move around so camera dot translate X okay uh let's move it a bit like uh like it should be positive for the right it should be positive yeah so 0.05 okay camera. translate it works it works but as you can see uh I press the right key but it goes it goes to the left uh why because uh it's not the cube that is moving so it's uh the positive number is the right if it was the cube but since we are moving the camera so we move the camera on the right we will see the cube on our left all right there it's logic so that's why so let's change it here negative number so we move the camera in this case on the left and by moving on the left the cube will go to the right or we will look like it moves but actually it's the camera moving not the cube let's let's try it again so press the arrow okay great so we press the right arrow key and it moves nice so the the same thing for the left uh error it was 37 so another uh another if so else if oh why a comment okay let's set comment for left AR key left AR key L if elif in this case elsf key code = 37 again comma uh camera. X because we are always uh on the x axis translate X and this time will be a positive so 0.05 Let's test it press the left we go to the left even though the negative is the left and positive the right but we are moving the camera as we said it is working until now so it's good sign we are having no more errors uh what else uh yeah up and down so the y y axis let's check for the the up arrow is 38 and then the down is uh 40 so 38 and uh 40 um up right yes up up Arrow key another else if if key code is 30 oh my God I I forgot in in a second and I forgot uh 38 okay again camera. Translate not X but Y in this case and the same Movement by 0.05 okay and for the down keyy another else if if key code equal 40 if I'm not wrong yes 40 camera. Translate Y acccept this time is negative 0.05 Let's test it so up okay I press up and it goes down so it's uh it's the other way around so here negative number and here positive okay press up okay goes up press down okay it goes down great it works so for now I think it's it's it's the same thing we can do with rotations yeah as we did uh yeah this is the idea uh I promised you that even if you don't know about uh event listeners you would understand in intuitive way right I hope so so pretty much is this uh we have this function on key down we call this function function in this event listener okay so we get access to this function to this event event. wit this event. wit gets the the code of this keys that we press and we call this function every time there is some trigger every time we like we have a listener there like it's like the name listener we have a listener what we want to listen we want to listen every time uh someone uh presses a key in this case because we are listening to a key down event so we are staying there and looking who is pressing the keys we will catch it okay so you are pressing the keys we are listening to you and every time you the the evant triggers uh we call this function onal when we call this function when we execute this function what we do if the key was 39 we move it to the right if the key was 37 we move it so every time we execute this function this is uh the idea I hope and I think it's easy to understand as I promised at the beginning so as you see until now 3js if you know a bit JavaScript it's not that hard let's say it's very intuitive the the names of the classes the names of the properties are you know are they tell something what they do so you can have an idea when you use those classes functions methods and properties uh I think uh we can stop here uh the moment so this is the code that we we wrote the last time we don't have much here we only have like a cube uh okay this one we only have this Cube I hide it the HTML here because I wanted to to show the cube last time okay so this is the the interface with this vangog painting some description information about the gallery and that's it for now I will hide it since okay this is an HTML element it's hiding the scene in 3D later we will do it uh dynamically when we click when we start we want to show the the gallery then when we pause or when we press a key we want to return to to the main menu okay like play or false so let's hide it again go at our main file so uh I will start with the floor the plane okay so we need the plane the ground and uh we will apply some texter to it to make it look nice and let's see let's see maybe then the walls uh the sailing let's see together so let's find a place where we where to start the new code okay so here we have the controls Keys let's let's start here above the controls keys so wait this okay so let's start with the floor create the floor it will be a plane floor plane come on it's my my co co-pilot it wants to suggest okay uh the floor so to create the floor if you remember in the last video we created the cube and for the cube we created first the the geometry of the cube we created a box geometry here it is so geometry new three box geometry and uh you have the comment here box geometry is the shape of the object then we created the material and the material is the color of the object the look okay then we create a mesh we called it Cube so this mesh accepts two parameters the geometry and the material like it creates this uh new object 3D object that has the geometry and material like merged okay so we will do the same thing with the plane with just small difference so L let uh plane geometry okay I think you remember here what we we should right so new always new for a new instance of the class that we are going to to to take so three uh this time not box geometry but we want the plane geometry intuitive right so Lane G geometry okay and it accepts two parameters we can go to Google and check if you want so 3. plane geometry okay here's the documentation a class for generating plane geometries yeah what we need code example yeah this is what we wanted to do create the geometry first then create the material then the plane that is a mesh that accepts geometry and material okay easy peasy then add this plane to the scene the same as we did with a cube that we have here in the scene okay so yeah we can copy this but we want to do it ourselves it's always good practice to always write down manually not copy past it of course copy pasting is helpful of course we need it sometimes we need to be quick but when we are learning who who for those who are beginners but even for those that has experience they are always learning something new at the point so when you are learn learning something new always write down the code it it creates this habit it then after a while it it it it becomes a second nature okay when you write it by hand by typing because when you make it a habit like to copy paste the code or you know use some kind of just a syntax help uh yeah it's very easy to forget even the most basic things like oh I need a map how to write the map or I need a function how to write the function or how to write the the component in reactor you know for everything it's it's normal it's normal I think it happens to everyone so without much talking let's create this habit of writing down but yeah the idea is this I wanted just to check for the parameters uh what parameters I see there are two parameters here I think it's wide and width and height let's check so width uh height width segments and height segments so it accepts four parameters this two should be optional yes they are optional so the first two that are important the width and the height okay let's do this okay let plane geometry new three plane geometry two parameters we we set so I don't know one was the default one yeah was the default one let's put it 50 for now who cares uh let's leave the optional parameters for the width segments and the height segments uh so in case you forget I will always write down the comments soof box geometry is the shape of the object okay so we have the geometry I think you remember now when you make this Habit to repeat the things again and again and again it will become hopefully a second nature so we need the material now so let uh plain material uh equal new always new every time you create a new object a new geometry material uh you know you will have this keyword new new instance of that class it's a new object uh don't care for now about the object oriented programming what's happening inside that uh you know parent and the classes you know three etc etc that we are instantiating don't care about that just think about a new I want to create a new geometry I want to create a new material and that's it for now at least uh so new three uh material right for material we see here it's mesh basic material okay so this one yeah I said we don't copy okay Mash basic uh okay suggesting yes we accept the suggestions so meas basic material it has uh the parameter an object and inside this object uh we put some properties key values right so open parenthesis and this object inside this object it will accept some properties uh for the material we said that it's the look of the object so the color this the simple color we will learn uh now in this video about uh other uh look of the object so not only the color the simple material but also adding the texture so you know customized uh look so we will give some image that we have etc for now let's create this uh plane that will be the floor of the gallery with a simple color just to to see that object in our scene just to render it so for that I think you you had in mind that we need color and let's give it a color like green okay uh another parameter it's here yeah it's optional but it's side and the side it's double side okay double side I will explain what it is this is to render both sides of the plane so yeah we created uh the geometry and and the plain material right so I want to ask you again I mean ask you you know just stop the video and maybe try to to to do it yourself what what what we need we said before when we create a new new 3D object we create the geometry and the material then in the end stop the video if you want without checking and uh try to remember if you create it that you know that habit so we need the mesh the mesh that we we pass the parameters of material and geometry so for that uh let floor or floor plane okay equal new always new three mesh parenthesis and it accepts the plane geometry and the plane material right plane geometry plane material that's it yeah uh yeah I would like to ask you again do you know what we forgot here what else do we need do we see uh no we don't see anything we forgot to add this floor plane that contains the geometry on the material to the scene for that simply writing scene. open parentheses and floor plane right that's it let's check if we can see anything yes we see it you see it looks like a background really not really of the floor of our Gallery it has nothing to do with the floor but yeah we will we will we will go there we will go there for now it looks like the background we added just a simple material a GRE one okay uh to give it a better look I mentioned before that there are no not only simple materials but we also have the chter okay so for chter we can add let's say something ourselves an image texter that we we have because texter are images that will cover the surface of our geometry okay and uh many many types of these textures can have different effects on the appearance of our geometry so it it is not always a simple material simple color we have like different types of of texures we have uh the color one or albo sign 3D softwares you will see albo the albo text is the the the most simple one it's you know it only chees uh the pixels you know and apply to to to the geometry uh then we have some other types like Alpha I think you also know Alpha part from albo that is the gray scale image and uh you know for the transparency it it it where white will be visible and black will not be visible then we have some more complex cheers uh we have the height Checker the high chter will move the vertices to to to create some some relief uh but yeah I will not stop here at the height we also have the normal uh that is also common used uh the normal cheers we add small details in the texter you know we it won't move the vertices okay but it will create the this feeling of of the light thinking that is is is the face is oriented differently so they are very useful and they are used uh often to add these details and yeah give that look of performance uh 3D object uh yeah we also have some other Checkers that I think you also know or heard or you s somewhere that is the the met the metal the metalness chter you know is that gives that look of uh metallic you know there is also the roughness that again we use it to to to to make the part rough and it's like with white and black the white will will give the part that is rough and the black will make it the part smooth yeah there is much to learn about cheers I invite you to go and check the documentation do your research it's interesting uh but yeah we will not stop here maybe there is to mention the PBR that I want to mention PBR because PBR now is you know it's everywhere in the most advanced uh 3D softwares because now PBR is becoming the standard for very realistic renders so Unity engine which I love my favorite uh tool ever Unreal Engine that is also great uh blender and many other so they they are all using PBR now as a standard you know for realistic render for now let's add a simple Checkers that will be a checker yeah that we find somewhere on Google or you have it I don't know I already have I think the Checker I yes I have the Checker here is this one you know a text her about the the floor uh yeah we want this in our Gallery you have seen the video so you know this you have seen it let's try to add this one how to do it let's see where we left where we left okay create the floor plane we are here so we need to replace this color with a checker not a simple mag material like color maybe above or okay here for the texter uh we need to use another class that is called texter loader this texter loader makes make it possible to to to to load an image that we we have like in this case our our image that we have in this folder here okay so the class is Checker loader we can Google about it we can Google about it 3 texter loader let's check the documentation class for loading a texter this uses the image loader internally okay okay so the syntax is const tter new three Checker loader. load or we can create a variable here for this separated so text loader let or con texter loader this uh new three then texter loader. load you know to have a cleaner code let's let's do it here uh so we we will go we will go for for what I said for texter of the floor okay so let texter loader new three let's check again was it new three checks the loader okay three check the loader was it lower case no it was other case you see this small erors okay now that we have this variable Checker loader we can access uh yeah this do load and add our image right it's just the same thing but yeah we keep it let's say cleaner with variables so text load do load right and check to load that load and we have Checkers and the path of uh of it uh the path is IMG then floor let's try IMG floor. J right should be okay I think so I don't see anything let's see the console look consider using plain buffer geometry for lower memory footprint okay yeah because now three have this buffer geometries maybe I I will explain it later the difference it's the same thing but yeah it was the old use was using you know without buffer now everything is buffer because yeah it it's a better performance for memory Etc with buffer you cannot manipulate you can but it's uh more difficult to manipulate vertices Etc but I won't talk about it now but uh I have nothing I don't see nothing okay yeah we don't have any error I think we can add it to we can yeah I think the that is not an N is just a warning about this plane yeah let's buffer let's see if it is okay it is not anymore there okay guys I was talking about before about the geometry and buffer geometry okay that I mentioned before that I changed here the plane from plane geometry to plane buffer geometry they are the same thing not the same thing but you know we will do the work but they have some difference let's say the difference is that buffer geometry not just geometry is the newer one in the 3js library okay with there is some years that we 3js had this update with buffer geometry and I will explain the difference now and I will explain why this bug that we couldn't see I think I got it why but I will show you you know to have this process thought to to to catch the errors because yeah this is our job to deal with with bugs and errs so what's the difference okay let's see this one I already checked this so I think so the guy here on stock overflow is is asking what is difference between box buffer geometry versus box geometry in 3js the question that we also have so the geometry classes are manipulated friendly memory unfriendly all JS geometry classes okay they are memory unfriendly we we learned that uh this means that each piece of data that defines this geometry is stored as an instance of some classes Vector 3 Vector 2 Etc these come with convenience methods so you can dot a Vertex with some other Vector translate vertices modify Etc something that I wanted to do before this project and that's why now I have some problems I will explain better please don't uh get confused I will explain everything but it has overhead in memory and performance creating all these instances and storing them okay so B4 3js has these classes of geometry only geometry not the buffer geometry now now it's been a a while I don't know how how many years but I don't know two or I don't know now everything is replaced replaced not really replaced you can still use this with older version but now 3js has updated to buffer geometry and buffer geometry classes are performance friendly geometry classes that rely on typed arrays to store the data okay in a webgl friendly format so they will use a float 32 array okay the guy here explains the difference what this means that vertices instead of being an array of vector three they are typed arrays okay they are typed arrays and they are much more efficient yes sure they are much more efficient but much harder to manipulate something that I wanted to do with vertices I wanted to manipulate and I I had the new classes of buffer geometry I I had no information about this thing that with buffer geometry I couldn't manipulate Vector three and vertices so I was having some problems I didn't have the information you see the difference look at the difference here so I will I was used with this method with the geometry without buffer to get vertex five and have access to its you know this is what you do and this is what you do with buffer geometry you see now the difference okay this is a problem that I had with another project and uh there was a discussion uh by the guys the that created 3js I think it's here yeah the upcoming release has this potentially breaking change the class geometry will been a longer part of the core and yeah it was deprecated in this geometry but as I said since I wanted to to manipulate this vertices with another project I uh uploaded the older version without the buffer so only with geometry so the older three object you know this the older one that has also geometry not only buffer geometry okay because I wanted to to do something else with vertices and yeah uh why so much uh explanation because here I think is the problem since I had this other version to use geometry instead I think this class uh three Checker loader wasn't in the in this let me check something else image yours okay and I have this one this now is deprecated with the new version this three that image youtil was used before this texter loader so you see in the 3js modules the big object in the source code of fjs there is this this class of image UTS and now this is duplicated since I have it here that's why the problem let me try just forget this guys I think I found uh the problem just forget about this don't get confused so instead of instead of where was it Checker the Checker okay here let me try something I want to try something else three image toils okay this is the class that I just showed you not it's not parentheses let me check again please three source code uh you don't have to do this you don't have to dig in the source code of 3js three image TOS okay three IM major deals load texter now we have the the the parenthesis for the path of our image so the path is IMG uh Slash l.jpg okay so new free image yours load texter I want to try this floor texter M floor texter I want to try this let's hope yes AA a Rea we found the bug it was a hidden bug it back but yeah this was the reason guys why I had all that talking before about buffer geometry and you know since I wanted to to create something else I wanted to to to manipulate the vertices Etc you know you you you saw here in the stock overflow the guy that was talking about that is much harder to manipulate it with this buffer geometry you see it is much more performant and memory friendly but it's harder for you know some other manipulation and it's it was easier with geometry that why I changed the I changed this uh source code of three I got this because yeah I could yeah sometimes with three you can play play yourself a bit so now no more talking about this we found this problem you just forget if you are using the new version uh download it from from GitHub if you are using the newer version you should have this one so this class Checker loader so you you can use this code here so I'm leaving it here okay I will add a comment here uh image utils is deprecated in the newer versions of 3js okay I'm leaving it for now because yeah I want it this way I want it this way so it's not a problem in the end so I I I will use this image utils but usually you know you you can use with a newer version Checker loader is the same thing so don't get confused again we have uh this floor that we created the geometry and material in then create the mesh that takes the geometry and materials and create this floor plane but to not have a simple color green that we had before but to have a custom image texter we created this texter that for to create the texture you need to create a new instance of this class texture loader or in my case image TS okay guys I hope it's not confusing I will leave the code like this the good news is that we can see we can see this our text are even though it's blurred and you know we cannot see but we see something that's a good news now let's try to to to modify and correct things with this new Checker and with this new plane that has this Checker okay we have addited in our scene no before here before uh we want to move this floor because you see it's very blurred and it doesn't look good we want like you know in the vertical axis like you know just the ground and we we we see it that way okay let's try to to do that so we need to rotate a bit this this uh this floor and to rotate there are some mathematics but uh don't worry we will not do Advance math we will use uh some internal methods that will do the the calculation for us okay so no advanced math for that to to to rotate the FL Flor floor plane do access rotation rotation do X we want to move it in the x axis oh that x uh I want to try to move it like 90 degrees okay and how you do that how you can move 90 degrees you cannot like write 90 here to do that we will use the the math. piy internal method okay so math. by divide it by two add the comment uh this is 90° rotation so if you want to to to to rotate something 90° use this formula uh formula math Pi ided by two okay uh let's see if we have we don't see anything now but we don't have any errors right no no errors but we don't see it uh let's uh floor plane do rotation. ya AIS this time and uh to rotate it in the y axis so not the the X but the Y we will rotate it uh 180 degrees okay so if you see that divided by two is 90° we can assume that for 180 de it's just math. Pi not divided by two right M that P this is uh 80° we don't see anything yeah I love errors I love when I have errors you know I forgot something here four plane four plane four plane where is four plane okay four plane it's correct okay the problem was the rotation I think I got the the AR where is the problem I think so so FL floor plane rotation X it was correct actually math. Pi that's it I made it's just a small mistake that's why I am not seeing the four so again y math. p okay so this was before and we didn't see anything okay the problem here was just a small detail for the y- axis not rotation but position AA position let's check now okay we see it finally even though it's upside down but we can correct it quickly so since it's upside down let's put a minus sign so minus 180° okay okay finally and that's it AA I finished this part here I had in mind to to continue with the walls but I think for this part I am finishing here okay and that's it we have our floor you see now we miss only the walls the ceiling and then we can modify the shape of this Gallery wide or you know then we can think about uh the paintings and give that very looking good that we have in the video okay that was the problem we couldn't see it because it wasn't I I finish this video now I will try to upload the other parts upload I mean I will make the tutorial and upload I will try to to to do it as soon as possible so you can finish this project so thank you very much for being with me and let's see in the next video bye and this time we will try to create the gallery walls uh as we did the floor last time uh okay I have opened my visual studio so without wasting time we can start by creating the walls so here is the code that finishes okay floor plane we created the floor here so below below we can start the code about our so let's add a common create the walls right for the walls uh since we we are going to create more than one wall so we need the front wall of the gallery we need the left wall the right wall and also the back wall and in the end we also need the ceiling we have the floor we also need the ceiling so since we need more than one wall we can create a group of objects uh 3js has this class of group when we want to create a group of objects that we know that they will be in this group you know to manipulate them together or we just want to recognize them you know for like in this example the walls like front wall left wall right wall and back wall there will be in this group so let's start by creating a group of objects okay uh I notice here I I used let and const so maybe we should be consistent and use yeah const for this thing the things that that aren't going to change like these variables for example yeah renderer cameras saying they are not going to change geometry also it is not yeah we can use const here but just to be consistent const cost okay yeah Sal andent light okay so this is our current scene what we what we have you notice that we can move the scene right we are actually moving the camera because at the beginning when we didn't have the floor we had the impression that the cube was moving okay we press the right arrow and the left Arrow the cube goes that way but now that we have the floor we can we don't have this impression anymore so we see that it's the scene moving actually it's the camera moving okay later we will change this and we will move the player the the person that is going to is entering the gallery okay let's go back to our code we are here create the walls make some space so let's create a group of walls const Wall Group equal three. group parenthesis uh leave a comment here create a group to hold the walls okay let's add immediately this group to the scene so we don't forget later so let's add this group to the scene scene. add you already know I hope this by now to add things to to the scene after we create something we add it later to the scene so scene. add Wall Group and this is done now let's start by creating the single walls so let's start with the front wall we enter the gallery we have the floor we will have a front wall in the end okay so comment front wall and again uh what what we'll choose for for the walls we used we use the plane for for the floor the plane geometry you might think that we can also use the plane geometry for for for the walls but we can use a simple box geometry that we already used many times right now so box geometry and also a simple material to give a color to it just to recognize in the scene the the wall okay we will create this box geometry but you would think that the Box geometry will be like you know like a box we need the wall but yeah but we will create the box with the width and with height but you know on the on the Z axis we will make it like thin thin very thin okay so it will be a wall am I explaining myself so const front wall equal new always new keyword to create something new three uh we can create like we did the last times we create a variable for the geometry we create a variable for the material and then we create a variable for the 3D object that is a mesh geometry that has inside the variables of geometry and material or we can use it in a code block so we can use a single code block to like this just to to to make things different so you you get used to to it to this idea you can use it like up above with creating a variable for the geometry creating a variable for material and another variable for the mesh that contains geometry and material or directly create the mesh having inside the parameters okay and with a main variable like this directly let's see it in action so front wall new 3. mesh okay parenthesis now let's create the geometry and the material so new three. box geometry okay open parenthesis and the parameters are the the three parameters for X for y and for Z the you know width height and depth and you know so let's give it like uh 50 20 and yeah we want this thin very thin we just want to to to have it you know the width and the height but thin not like a box so 0.01 or 001 let let's see it okay comma and now we will add the material you see they are in a single block of code not by creating three variables you can use it either one or how you prefer but I want to show you you know to get used to it new 3. MH basic mat iial uh parenthesis and this accepts an object with some properties that we can add so object inside this object we have the key value of color green red blue okay so the property of color and the value of uh let's make uh each wall a different color so we can separate and recognize that because if you if we make like red red red you know we don't see the the borders you know so let's make every each wall different color let's start by Green okay and we created the mesh of the front wall do you remember what we need after we create the geometry and the material and the MCH containing this geometry and material uh I think you you remember it we always need to to add this to to our scene okay do not forget because if not you will not see it in the scene but also we need to to position somehow this wall because we want to see it you know but first first uh let's try to add to the scene so to add to the scene we will not use scene that at in this case since okay you see here we already added this wall group to the scene okay so the group containing these child okay these walls will be added to the scene since we added the group there okay so if we say for example W group. add and we add here the front wall then we will have the left wall right wall etc etc so since we are adding this front wall to the group Wall Group here it will be automatically add the to the SC since we added to the scene the Wall Group I hope I am explaining myself uh yeah we can we can try and experiment live okay let's see what's the error 3D object. add object not an instance of three objects 3D undefined okay okay let's check so Wall Group 3. group uh first of all we created this this this group okay and seeing that add Wall Group we added uh the Wall Group to the same we are okay here then then we want to add this front wall to the Wall Group okay so wall group. add front wall and is this one here okay uh I forgot the keyword new that's why it's not an instance of okay forget it so it should work now yes okay okay so we have the front wall but we have it you know to Too Close and but we have it so we are there uh very easy very easy now we can change the position you I hope you know by now to to change the position and have clear this idea to to change the the position in different axis on the x axis y AIS and Z AIS so in this case the front wall it's in front of us okay so if we move the position in the X AIS it will be still there to close but just moving left and right if we move it on the y axis we will move it up and down so what we need in this case with the front wall is just push it and you know give it some space we want to push it forward and that is the Z axis okay so the depth we want to push it forward so let's change the position on the Z axis because I think the left and right so the X and the Y let be on the Zero you know this the by default we are not going to change it we just need to change the Z axis let's try so here front wall that position Z we said and give it a value of so as you know for the x axis uh positive number is right side negative number is the left side okay zero is the center so if we give a value of positive number uh the object will move will translate the position to the right if we give it a value of negative number we will move it to to the left so the same with Y and the same with Z in this case if we give a positive number we will have it to close so in this case let's try with a negative number okay and the negative number of uh I don't know 10 let's try it okay 10 looks looks great because maybe I think we gave the of the floor we give the same value of 20 as the height or you know whatever 20 20 is is uh looks looks okay so we have this front wall of the Galler of course we can change the values for the width it looks perfect for the width it looks okay we will match it uh with the width of the floor we will check but I think it's 5050 because I I remember that the floor was uh 50 as the value so also this wall here is 50 and it it matches uh for the Y it looks okay maybe higher I don't know but it looks okay for now higher will be to much maybe I don't know we can always turn turn back later let's leave it like this we added the front wall let's start with the other wall the other wall yeah the left wall left wall so again like with this method above create a mesh that has inside geometry and material or create separate variables for the geometry separate variable for the material and then the variable of mesh containing this as you prefer I'm trying to do things differently so you get used to to like the idea so const uh variable left wall and this variable will have this instance of the class mesh from three this is uppercase three is always uppercase three do mesh parenthesis accepting two parameters the geometry don't forget the keyword new as I had the problem before when you instantiate a new instance you you you you need the keyword new because you know from object oriented programming for example this mesh class uh in the you know in the back scene would have a con Constructor with some properties you know we get some properties from this class okay but they these properties of the Constructor are Dynamic so they have a key that we can give a dynamic value to it for example so the mesh has some properties defined there and we can just give new values every time time we create a new instance of it so for example this mesh class would I think would have a Constructor normally it has a Constructor with some properties defined there uh we can give to these variables these properties uh Dynamic values every time we create a new instance so that's why knew this and knew that okay we just create a new instance of this mesh class that was defined there with its properties okay but every time we create a different instance with different variables we get a new one a dynamic value for these properties okay without confusing anyone let's continue with new uh yeah the geometry right yeah geometry new three uh do box geometry again parenthesis uh let's give this value again for front and from from left let's try it with the same values the same width and the height and the Z axis so 50 20 and 0.1 comma don't forget comma here and the next parameter which is the material new three do mesh basic material it's the simple material parenthesis it accepts an object inside and inside this object we can put some key value like color red color green Etc we have green the front wall let's give it another color so red color red okay and now after creating this uh I think you you know by now we need to add to the scene so left wall add to the C and it should be okay okay we need to position it but let's see first yes we have this left wall but as you can see here and as you can imagine as with the front wall it is again in front of us with front wall we did nothing but just pushed it forward in the Z axis okay but what we can do for the left wall because the left wall we need it like this you know like in a vertical axis so we need to rotate this this wall from here we need to rotate it like this okay so like this so we need to manipulate the rotation in this case uh not the position we need to just manipulate the the rotation of course the position also we we we will give that value but most important here is the rotation so from here here is like n sorry it's 180 80 degrees okay so no yeah from here here we need to move it no sorry it's 90 degrees actually yeah here it's 90 degrees because 180 deges will be like the floor turning again okay so it's half half this the the the sphere so we we need just 90° in this case and 90° if you remember the the last tutorial for for the 90° we can uh we can use math. Pi ided by two formula okay when we want 180° we use math. Pi 90° is math. pi divided by 2 so 180 ided by two let's try that okay here left wall left wall do uh rotation rotation okay so rotation in the Y AIS right's try so math. Pi Pi is uh uppercase uh divided by two this is 90° let's see what happen what's happening we cannot see it okay because we we we rotate it but we cannot see it it's not in the scene we rotated in the y axis it's not in the scene let's move it let's move it uh let's move it in the xaxis I think we cannot see it because let's move it in the x-axis don't don't don't get discouraged guys we will get there so let's move it in the x axis okay left wall. x. position position. x equal uh in this case if we said the positive number is the right and negative number is minus okay so negative is left positive is right so we have the left wall negative negative negative again negative 20 let's see what's happening oh error okay cannot read properties of undefined reading position when you see an error like this usually it's like the property that has this position doesn't exist or there is some problem there is some error with it okay so we cannot read the properties of undefined so position is a property of this undefined what is this undefined this undefined is X of course because you see position of undefined undefined here is the x that I don't know why I wrote that it's left wall. position. X not left wall. x. position. X okay but yeah you you should get used to understand the errors what they mean really you get used to it when you get often bugs and errors like me I I get a lot as you can see I make mistakes but I hope that I also learn from them but you should get used to the meaning of this errors it's like those very important things in programming and for developers yeah it has some meaning so it was undefined yeah we see the wall and it's perfectly fitted we okay that's great that's great you see we also have the left wall and this property here was perfectly I just want to try not math that uh pi divided by two but 180 degrees and you see as I said one math. Pi like make a rotation 180° okay so it will turn again from the other part okay like back in this case we need just a 90° from here here 90° okay it's like this I think you have this clear but you can always play you know if you have problems in other projects so divide it by two and the position was the the because if we try this not negative but positive you will see it now at the right the same thing that we will do with the next wall so okay you see it's on the right side but since we named this uh left wall we need it with negative number now we can easy peasy create the right wall because it's the same thing here we can just copy it but we said that we don't copy we manually type because we want to create this practice and habit so it becomes with practice second nature to to not forget how we write code call things functions methods Etc properties left wall now comment right wall and con again right wall equal new instance three main object mesh class parentheses and mesh class has these options that we get from it ready made it's properties that we give a dynamic value every time we create one we we we can give another value different value so the first one is the parameter for the geometry so box geometry uh new oh new okay you see this small errors but they can create a bu three. point geometry all the geometries are are always from the main object three okay so three is the main object I will I will show you here this is the source code of three you see there are how many lines okay we have like more than 355,000 lines okay full of this classes methods Etc so VAR three this is the main object and then inside this object we create classes with Constructors with some properties that we have defined there that we can give new values every time we instantiate and create new instance of this classes and this uh classes may also have methods that aren't anything else that simple functions so methods are functions declared inside an object and we access them we access them like mesh dot. function so it is called the method and yeah you know three is the main object here that has inside all these classes like mesh that has these parameters that we can pass geometry uh value again 50 20 and uh 0.001 comma don't forget and new uh three again mesh basic material parenthesis it has an object inside this object has some properties like color with value uh yellow this time we want to differentiate those colors yellow good so this one is easy peasy because it's the same with the left wall so but we don't copy left wall. rotation again the same thing oops rotation Y is it y or yes y math. Pi formula to rotate we will always use this formula oh my God this word is so difficult for me we we will always use this formula for rotation 90° or 180° 180 Dees is math. pi 90° is math. pi divided by two we want this 90° so math. pi divided by two and again I will leave a comment every time so it will stick in your mind this is 90° I want to make it stick in your mind and position left w. position uhx equal not minus 20 but 20 positive number positive is right and what else here guys yes you know we add it to the scene and we don't do scene. add we do WG group. add because Wall Group is already on the scene so we we just need to add the Wall Group on the scene and the Wall Group will add everything that has inside as parameters pass here right wall and we don't have any more errors no okay we have again the wall but I changed the position position why um rotation y ma ided by two and position is 20 then why what this happening here do 20 are okay where wall right wall Warrior you are on the front what am I missing here guys I think you you are quicker than me to find the arrows I'm sure left that position that Tak oh my God okay okay I you you I I am completely sure that you of course you you saw this this this stupid error from me right I wrote here I changed again the position of the left wall the same thing I did here it's the right wall right that's why but yeah we learn from the errors let's check okay good we see it we have different colors you know we will in the end we will give White Walls to this but if I make it white we we cannot see the difference because also the background is white and we cannot see we just see just a big white well okay looks looks good until now so what's left it's just the sailing right we just need the sailing now let's set the sailing right and the sailing for the sailing uh do we need to create for the sailing in the same group here that we have this guys here the walls no because the sailing will be separated from this as it is separated the floor the floor was a plane geometry right so it was not in this group of walls so also for the sailing we will create a separate 3D object okay and not a box geometry but this time again like with with the floor we we will create a plain geometry So Below this okay sailing so again the old method we create a variable for the geometry we create a variable from for the material and then we create a variable for the mesh that contains this final object okay or you can use again mesh inside let's keep things different so you get used to it once you get used to the idea how it works behind the scene you have it easier to to develop things so again with the old method with variables so con uh the geometry sailing geometry equal new three that uh this time plain geometry and plain buffer as we said buffer has is memory friendly so has better performance uh is better for the memory and you know it's the new new 3js new plane buffer geometry uh we had 50 here for the width 50 for the width so the sailing will have also 50 for the whe but yeah also 50 for the y axis let's do it 5050 5050 okay I will I will not get charred on writing comments I I will repeat the same comment every time we create a geometry every time we create a material it will stick to you I'm always uh referring to beginners guys so if you are someone who has experience uh don't laugh at me that I repeat these things again or don't get bored because okay I know that maybe you are uh good developer you don't need these things to to be repeated 100 times but uh actually I'm refering to beginners because yeah this tutorial was let's say for beginners not only but yeah so bear with me some passions when I repeat things so box geraty is the shape of the the object now let's create the material sink material new three object main object and mesh basic material class uh for material for uh the sailing we used the red green and yellow red green yellow let's use blue for the ceiling so do you remember inside the mesh basic material we have an object and then we have this properties of color or blue Double D dou do okay we created the sailing what else we didn't create the sailing because to create the sailing you create it with a mesh so const saling linke equal new three main object mesh class and uh pass here sailing geometry and sailing material okay now we created the sing but we cannot see it of course we cannot see it because we should add it to the scene as we always do so seeing that that uh what's the name sailing plane okay now we should see it but again we need to position this sailing because yeah I think we will see it again in front of us yes we see it again in front of us so yeah it's another object that we see in front of us because we need to position it so for the other geometries we rotate 90° like this or 90° like this so 90° and then position it to the Y axis minus 20 or positive 20 this time we need to rotate it up above so we need the sailing like like this rotate like this so can you guess how how we can do it want to try it yourself maybe okay how we want to to to to to rotate this on the Y AIS uh not not in the y axis because in the Y AIS we did with the with the walls so it should be in the x-axis let's try let's try I hope I'm not wrong on the x axis but yeah let's try let's try so ciling plan uh rotation mod by ceiling plane do rotation that let's want to try y maybe first I think it's X but well let's try how we see it with with with Y AIS uh sailing plan rotation. y math. Pi Pi is always uppercase divided by two 90° this blue hurts the eyes that by oh oh I was seeing that is like a bit rotated and I was wondering why uh you see but uh yeah I divide it by two not by 90 we cannot see it because it's not uh there inside the the scene Let's uh move it a bit in the y y AIS so we see it sailing plane. position. x uh let's try 20 we cannot see anything 50 we cannot see anything 20 10 we cannot see anything so we rotated it in the y axis so let's try x axis so 90 Dees in the x axis again we cannot see anything 15 I cannot see anything Rotation byid by two oh we have x x you see the RO the rotation will be y not where around so the rotation will be Y and no not y y was for the walls the rotation should be X and the position should be y okay we see it we should move it uh down so in the Y axis so 40 no 13 no 12 okay fit perfect we also have the sailing we complete this looks nice yeah but one thing I want to do I want to do something because uh later when we will will create the player and the player will go around the gallery when we go near the wall we want to have a collision we cannot pass through the the wall okay we cannot break them through to the other side we want to have a collision and stop there because we are not ghost we cannot go uh through through through the walls so for that we will add the collision and to to add the Collision uh there are some ways and they are different from program to program from 3js or Unity or in real but the idea is to add the collider the collider is you know like uh bounding box that it's the same as the object that we want to add that collider okay so when we go near that object we collide with this box collider and so we will stop there by adding some other coat okay but the idea is to add this collider so later when we will create the player and the controls to move right and left we want to to stop when we go near the walls so for the walls here to create this bounding box first of all let's loop loop through through this walls because we want to add to each wall this bounding box okay so here let's Loop through each wall and create the bounding box okay so a for Loop uh array. length it will be not array. length but it will be W group W group. children. length so the W group that we have that has the children that are all the walls left right and the front so Wall Group do children length Okay so we are looping through through this walls and to add the bounding box we access this B box B box 3G that is okay so equal so w group children I that is the element each element that b box equal new three boox 3 okay this creates this again we need W group. children I element we will will use another method here we will use another method here that is called set from object and this set from object will pass this W group. children I let's switch this yeah this set prom object is to compute the bounding box of the children inside including it children so so to create the bounding box not of only one object like with B box three but when we have a group of objects we want to create a bounding box for each of the children in this group of objects for this we use this method set from object okay that's it and here it is we also have this bounding box for now we leave it here because we we will have to do with it later when we will collide the player with this walls but yeah this is for now we can finish this tutorial and see in the next one when we we add the paintings and yeah we will modify our scene make it look better okay see you in the next video and thank you for being with me uh the main changes uh before we we we we begin where we left uh is that I updated 3js uh with the latest release okay so now we have the latest release of 3js which is a good thing we always want to have the newest updates from 3js also I added a build tool which is uh V or vit I don't know how it's spelled but it's lighting fast you know if you know Vite Vite is a build tool and it's uh lighting fast to build uh the server to run our project so we don't have to you know go live here with the option or have the three file downloaded and uh have it here on our local as we we we had it before uh we will download three from mpm as a package I'll show you so search on Google uh 3js installation click on it as you can see uh here it says that we need the projects structure and first of all we need an HTML file which we we already have main JS file which again we we have uh then we can import uh import uh Star as three from three so import everything as three from the three package uh we also May create a public folder which is also sometimes called uh static uh here we have like all the files like the media files uh the 3D models uh assets uh and everything um then you need to to to run this commands so install three with mpm so mpm install D- save three it's to save this uh in the package Json dependencies uh and also for Vite or VD npm install uh VD run this command okay I already have it that's why I'm not running it now but you can find it on documentation and run this after installing mpm install three and V you will see you will have the a package Json okay and in this packet Json uh you will have this section here dependencies and Dev dependencies where you will see the version of three which is the latest one okay and also for V if you have any problem you can simply go uh on my GitHub check the link in the description uh copy this file package Json or download the whole project but if you want to follow along just copy this package Json edit it here in the root at the root level okay and then you can simply run mpm I mpm install and it will install the dependencies that I have here in the package as if you have any problem now we will start the features that we want to add this time uh if you remember we left it the last time we created the floor the four walls the ceiling and then we said that we want to create the paintings on the wall and also the camera movement like a user enters the gallery and moves around in an immersive uh experience way with a camera movement we will do that and also have the menu like we click the start the play button you know and then we can pause we'll see we'll see together first of all uh what what we would need first we need to import for the movement let's go to main JS oh also I forgot I also I I changed the structure of the folder now you see the not modules of course because we installed three invite so you will see not modules uh I added this structure uh folder SRC inside SRC you will see the folder public which we mention is for the assets media models Etc the HTML file of course the MJS for our script and yeah this CSS so and that's it you can yeah take a look here and uh follow as well this folder structure to be you know to have the same the same project or you can download from from GitHub okay uh as we saw in the documentation the first thing first after importing uh after installing three invite uh we need to add this yeah import Star S3 from three so here we don't need anymore this cono log okay we import everything at three from three and we will access it here okay so now this variable here three will be accesses everywhere here okay then uh we need to import the the controls for the controls we don't import them from the main three class main three object actually but from another import and I will show you we are talking about about Pointer log controls okay it's what we need pointer lock controls from three STD leap Library you need to you need to download this okay to install I have it here on my package Json installed you need to run mpm SD lib here okay run the command and uh install it or as I said copy the Packa Json that I have on my GitHub and simply run mpmi it will install all the dependencies after having this and importing it here we will use it later uh for the controls something else I I I I changed it's I I want to replace the deprecated image utils with texter loader I left a comment uh in my code there uh let's see image details okay it's here you see for the texture of the floor I left a comment here image yours is deprecated in the newer versions of 3GS now we have the newer version of 3GS we have the newest one okay so we will delete this image utils which is duplicated and we'll replace it with another class of three which is texter loader I will show you so here delete this part okay and instead okay up and instead create a variable Checker loader Checker loer equal new as you remember we always create a new instance of that class so new three uh textor loader okay it's a method so now create another another variable const floor texter and assign it to texter loader. load okay and here pass the path or the the URL of the image for the floor for the floor we we add an image here in Public Image floor. jpeg okay so here with v we use uh this way we don't uh type oh sorry we don't type here public Etc but we simply add come on simply at EMG slash floor. jpack okay of course it's a string like this not the absolute path like SRC public etc etc simply add IMG floor plane jpeg Etc okay and that's it now we have with the newest version of three we are using the texter loader and not any more image utils and this is fixed uh what else uh yeah we want to to to add the paintings okay so let's create the the paintings for the paintings we will create uh a painting mesh with a given image URL okay so a mesh with a image URL and also it's dimensions and also its position okay okay so let's create this function that will accept this parameters uh let's create it somewhere yeah maybe here after the the sailing and before the function for the movement okay so function uh create painting create painting okay and as I mentioned it will accept uh some arguments that we will pass which are image URL okay uh with also height uh position which are things that we need for our image okay open curly brackets and here we will create the logic for creating these paintings okay so inside this function we load the image texture and create a painting mesh so the complete function will look like this with this logic first of all we need uh a texture loader again so for that as we did with the the floor uh a few moment ago uh create a variable const textor loader okay uh as always new three text loader okay then we will create a variable for the painting texture so con painting texture okay that will be with using the load method from texter loader okay this is uh warning me that okay it's uppercase so painting texter will be texter loader. load okay and as a parameter here we will pass the image URL which one this one here that will be passed dynamically every time we will use this function you will see so here pass image URL and this is done now we create the material const painting material equal new three mesh basic material I think you remember the mesh basic material that we we we covered in the other videos basically we have an object inside and we use map okay and we pass the painting texture if you remember you should be familiar by now with this and also we create the geometry for this uh paintings so const painting geometry okay and the geometry is made using a class from three in this case it will be what kind of geometry it will be a plain geometry because yeah it's a plane so uh new 3. plane geometry okay this plane geometry we will pass two parameters width and height of course so width and height so yeah we will create the mesh now we have uh the texture we have the material uh we created the geometry and now we will create yeah the painting because the painting will be as if you remember from the previous videos you know that the mesh is made with the geometry and the material okay so in this case con painting equal new three mesh it's a mesh what we want and we pass as we said the geometry and also the material the geomet is the variable here painting geometry painting geometry and the material is this one painting material okay and this is done yeah we we have this function we need to return this function of course because we will use this function so it it should return what it should return this painting Okay so so return painting and this is done maybe maybe yeah of course we also we said yeah we we want to use also the position when we create uh the painting every time we will use this function to create a new painting we will also use the position we will pass a position for it okay so here before returning U painting that position and in this case the position will be uh first we will use set to set the position and the position will be this value that we will pass position uh that X position y position. z position. x positiony position Z okay and that's it uh for for this function create painting we created this function so what else with this function let's add the paintings to our scene to call every time this function we want to to create one okay so we will create for example two paintings now with different images and different positions so to do that we create create a variable for let's say painting one const painting one okay and we will call this function that we just created create painting and here we will pass first the path or the URL of the image uh I already have here a folder artworks with all the works by vangog so let's use some of them it's uh simply artworks without SRC public Etc artworks okay and then um yeah zero. jpeg Z okay the first uh parameter uh the second one width and uh height and also the position I will give 10 five here okay let's see and for the position we will create uh a new Vector 3 class for the position so we will uh create a new instance of vector three so new uh three dot Vector three okay and we'll pass uh the values for as you see here X Y and Z okay I don't know let's give some random one in this case uh but yeah for the X let's say just 10 minus 10 for the left for the Y uh positive five and uh uh for the Z let's give it 20 negative 20 okay painting one also let's create another painting we will put it at the front wall so const painting two call the function create painting again every time we will create a painting we will call this function okay it's it's very useful as you will see so create painting and again pass the arguments in this case the first one is the URL yeah artworks art works then one. JP okay also here slash I think uh the same thing but this time not negative but 10 okay five and also minus 20 should be okay and again for the position new three do Vector 3 and pass here uh the values for the position in this case again not minus but positive number it will be uh left and right so 10 5 andus 20 it should be okay now that we created these two painting if you remember every time we create an object a 3D object we need to add it to the scene because if not we will not be able to to to see it okay so I think you remember this scene. add to add the things to to the scene and pass paint painting one and painting two oh we should be able to see something I think okay we might have some errors cannot assign to read only property position of object 24 Let's see we don't need actually this line so we can remove it let's see yeah now we see something we have another error but yeah we can fix that we can see yeah we can see the scene we don't see the paintings okay we have a problem use them and we had another arrow uh okay let's fix this one first of all let's fix this plane buffer geometry has been renamed to plane geometry three module okay PL buffer geometry let's fix that first okay it's been renamed to plane geometry right plane geometry yes because now we are using the latest three JS so remove the buffer one okay Lane geometry okay this is fixed uh not found so yeah maybe the title is wrong floor plane yeah it's wrong it's floor okay now we see the floor okay but we don't see the paintings yet let's check oh yeah maybe it's let's try 18 yes so let's use 90 because I remember 20 was okay you can see 1999 yeah 20 is the limit okay also here can we see the other one we don't see the other one why artwork it's okay width height oh this one what is this it's not the this parameter it should be okay yes okay as you can see guys you see the paintings on the wall it works and we can use that function every time we want to create another painting we use the same method so painting three painting four painting five you know you can call every time just create painting function and create as many paintings as you wish we can of course create like function like to create like 50 paintings uh at once without like calling and creating manually you know painting one 2 3 4 of course we can do also that but we still don't know how many paintings we want to have for now for the sake of this tutorial we I will leave it here just these two paintings okay it's the same logic so maybe you have it as a small challenge yourself to populate uh all the scene with with other paintings okay so it's up to you in the end if always if you have any problem of course I will I will do it we don't have any errors right no we don't have any errors we are good to go so we want to create now uh the movement because we don't really want this movement you see I press the right arrow and I go left I press the left arrow and go right this is because initially we were moving the camera and had the feeling when everything was empty the scene we had the feeling that the cube was moving right and it made this idea we were moving right too but no not that we have other objects of reference we see that I press the right the cube is moving to the right but we are actually moving to the left so we will change that also I will have to add the keys W S A and D to move not only the errors but you will see that I will add this pointer lock controls basically you move the mouse and you move around in the direction of of of the mouse uh why we need that we need that because it will be smoother movement because I move the mouse I like look around and then I can move with the arrows or wsda a I can move the mouse and then move forward or in any direction it will be smoother and a better experience you will see so let's go back here so we imported at the top the pointer lock controls okay you installed this now uh let's use this uh pointer lck controls okay we create we will create an instance of pointer lck controls and connect it to our camera and the document body or maybe let me think a second because that's how pointer lock controls works we need to click at something and it will activate the lock so we click and then let's say the controls start okay then we presses in the keyboard and the control locks unlock meaning they are deactivated we cannot move anymore what we want is click the play button uh enter the gallery then we can move so we want to add an event listener to the play button to lock to start the controls okay and then uh n listener when we press ask they will be deactivated okay and in this logic we want to hide the menu after clicking the play button we want to start the controls but also hide the menu because we will enter the gallery but as soon as we press the ask key we will deactivate the controls and display again the menu so we will have the chance to play uh the button again you know so like play or not play let's see let's see uh for this so let me find a a way where we can add this maybe here yeah here before before the the function on Q down okay we can add that so uh control okay create the variable controls and always new the new keyword to create a new instance of pointer controls pointer log controls and pointer log controls we will attach the camera to it okay so camera and also the document body document body okay so we will click and we will uh activate this so we need to create function for that okay to start the the game the game it's not the game but to start our journey our tour okay let's call it experience so let's create a function uh let's call it start experience okay lock uh lock the pointer I will explain log the pointer uh meaning uh controls are activated okay and hide the menu when the experience starts to start the experience we'll create a function called start experience uh that locks the pointer and hides the menu locks the pointer meaning activate the controls okay and we'll also add an event listener to the play button to start this experience so function start experience okay and here we will add our logic then as we said we use this function start experience that inside will hide the menu hide the menu and here lock the pointer okay and we said that we'll also add an N listener to the play button to start this experience okay because this is the function but we want to add it to to to to the button and the button is uh okay the ID play play button is this one yeah is this one okay so create a variable for this play button play button and it is document uh this is pure JavaScript okay uh get element by ID get element by ID okay it was play button play button I think underscore yeah play button score okay okay so we have this play button bar uh variable and now let's uh use it play button that add event listener we add an event listener to it okay so when we click we will we will use this function stat experience we click this button we fire this function okay for this it's always JavaScript it's not 3js click the name of the event okay it's the name speaks for itself and the second uh argument is the function that we will fire start experience okay so on click fire this function that we will finish here the logic so we said we want to lock the pointer inside the start experience function we will add uh the lock pointer and hide the menu as we have the comments here for that for the lock of the pointer we simply uh add here controls. loock yeah simple as that simple as that and for hideen menu yeah let's create a new function make the code clearer so uh create a new function let's call it hi hide menu because we will then later also show it yeah we we'll create two function hide menu and show menu so hide menu okay created here this function hide menu to hide the menu it's always JavaScript and to show the menu the same thing hide menu function hide menu okay we will grab the menu because what what we will hide what menu this one uh okay this one with ID menu It's the whole element so const menu again we will refer to to do this document javascript. get element by ID and it was simply menu right menu yeah now that we have this uh uh variable menu we can hide it menu. style uh menu. Style do. displayed and as we said none we hide it simple as that okay so this function is used here in our start experience we also want to show it later so show menu it's pretty much the same thing show menu we can just copy this okay the only difference is not none but block okay so we have these two two functions uh we are not using the show menu yet because What's Happening Here document okay typo document where are you where are you document okay here another okay uh cannot read properties of null oh yes of course it's n okay oh because I commented out this I commented this this of course it's null because display button doesn't exist here it's null yeah simple as that yeah uh you see I click this button nothing happens but I activated the controls I press ask it stops I click but okay it's working like it's triggering the controls when I click click ask it stops but the menu is not hiding let's check okay okay guys I I saw the arrow as always I sometimes make stupid mistakes so bear with me yeah it happens very often uh I don't know why I just forgot the syntax uh the basic syntax of this we just assign to n okay and also sorry here's block and here is none but we assign To None don't pass it as a parameter okay okay just a stupid error it should work now we click HIDs okay great presses it will show again and stop we click controls are activated and the menu is hidden presses okay controls are deactivated and the menu is back okay it's done everything correctly okay I have up and down but I don't have the forward and backward movement I will add it we'll add that now and we are done I think with that feature let's Ed it here we have the key codes and we just need to to add the forward the backward uh movement uh yeah also add for w and uh D A and S keywords okay so here uh we will modify this the right uh the right arrow key 39 is for the right arrow key uh I also know that here we can add for uh the right is d right yeah is D here we can do or if key code equal 39 which in the table we showed the last the last time we showed the table that every key has this key code okay and for the keyword D is 68 so if key code equal 39 or key code uh uh equal 68 okay uh in this case we will not use translate X or Translate Y we will use uh also we will not use the camera movement here but we will use for smoother you will see we will use the controls movement okay so here uh instead of camera. translate uh X Etc remove it and add controls. move right simple as that and pass uh Z Point add more speed uh let's try eight 0.08 let's try the left okay yeah yeah you see it's better okay uh we'll do the same thing for for the others okay so also here that we have camera done translate x uh controls that move right okay but we'll also add here uh this is left so if key code equal 37 or key code sorry or key code equal 60 60 uh 65 is for for the the button a controls uh move uh move right yeah but we can add the negative here okay or move left left let's try should work also I think okay uh this doesn't work yeah this doesn't work works okay um move right but add negative here right Works left works yeah perfect okay great so use controls that move right but use the negative for negative for left and positive for right okay so up C and down so I don't want this y camera I Want U controls forward and controls backward okay for that uh we will use again the controls but first if key code equal 38 and also uh uh key code uh equal uh 80 87 yeah 87 is for for for W uh controls. move forward and here again 0.08 okay the same the the same speed you can change the speed uh As You Wish Al here also here as with move right that we changed the negative for moving left the same thing to move backward use move forward but just add negative uh negative value here okay so negative it will move backward but for the down uh which is the the S key if key code is equal uh 40 or if key code is equal 83 which is uh the S key move backward okay because we have the negative here let's test it should be correct yeah it should be correct click activate controls we move around and let's let's try to move forward okay forward works like a charm backward works like a charm left and right okay it works so for example I want to go this way you see that it's smoother nicer because I can move the mouse and yeah just by you know it's better like this okay guys that's it we we did it I will leave like this small uh challenge let's say for the beginners of course to adjust yourself the scene to add more paintings on the left and the right walls uh the movements are are okay you don't really have to do anything about it you can change you know the colors because we have this strange colors for an art gallery but if you remember I added these colors just to differentiate you know and see uh the walls and the ceiling uh in the next tutorial I will try to optimize this of course make it realistic I will try to play with the lights I will try to to optimize the chter we want to see the walls as real walls uh yeah optimize it make it look much better maybe okay if you did it yourself at the time for the paintings I mean if you are doing it yourself uh it's great uh if not I will do it so you can check if you had any issues with positioning the paintings on the wall but maybe we can add like I don't know a better way to display okay so see you in the next tutorial thank you for following me bye in the last tutorial we built the foundation of 3D art gallery setting up the walls the sailing the floors adding like a simple Cube we also implemented a basic movement controls uh Etc since then uh our gallery has had a major upgrade and this time uh I added real artwork implemented Checkers to make our Gallery look even more realistic uh yeah I'm sure you can find better texter very high definition out there so yeah feel free to find even better textures and yeah we even added a dynamic lighting system to set the mood a bit uh I will show you uh but yeah I improved some other things like movement I got feedback from someone commenting on my channel uh so now we have a better movement controls it is smoother now I fixed those things but I've also worked on user interaction and now when you approach a painting an info card will appear displaying details about the artwork okay I will show you so you see the textur on the walls now the walls and the gallery looks better as I said we can find better textures of course but I didn't want to use like very high definition textures because yeah the performance uh will be you know you see also the angles the borders uh it's they are better defined now because the Shadows are showing better and the lights so you now it really looks like a gallery you know like a r but I want to show you the the new feature that uh we have now okay you see we have an info card it will show yeah the title the description Etc when you get close to to the artwork you go away it will disappear you get close it will show if you change to another one it will show show information about the other one and it's a nice thing this is a feature that many many people requested me even writing me on private so not only on this tutorial but also in the other tutorials uh this I I saw that this was a feature that was nice to have from many of few so yeah I addit it and we will go through it how to implement it step by step and I also am commenting every single line in the code on GitHub so for those of you that are you know are not beginners uh please bear with me I know it's not the best thing to have like comments on every line but for the sake of our tutorial for the people that uh really want to learn the basics and they really want to understand every step not only like look at me I'm doing this look at me I'm doing this oh now we have this and you just code there you know there are many tutorials when the guys just code and you follow and copy paste and yeah you get the project but in the end you are not really sure if you really understood the things and the next time that you want something you will always rely on that YouTube tutorial so the secret actually is that uh those who makes tutorials they want this they don't really want you to you know to learn how to do things yourself or uh they don't really want you to to create things yourself to to to to teach you how to do it why you are doing this okay so uh like uh you create a variable why you are creating this variable how did you know that you need this variable how did you know that you need this function why this function what does it mean you know how can I know that oh I would need this function how to to to to make the the you know the problem solving how to debug things how to solve problems so this actually are the most important things to to learn for everyone not only for the beginners but yeah we know that uh many tutorials they just you know teach you how to rely always on those tutorials so you will always come back to to their channel to their tutorials and yeah copy paste and follow the video they are like spoon fitting tutorials okay this is why I will explain every step I will comment every line of code on GitHub so those who are experts please bear with me just ignore the comments you know but I think for other people uh the comments will be very very helpful even if you understand it now maybe you will get stuck and you will forget okay and you can turn back at the code and see okay this is about this this has this function this means that etc etc etc okay I hope it will be helpful if not please tell me or if you have any ideas if you have have any suggestion what you'd like to have you know what you'd like to explain more or what you would like to just stop it amilon just stop with this blah blah blah and just go and code okay uh I also changed a bit the menu you have you you see there are some slow animations um yeah the fonts and everything yeah the pencil the the mouse now the pointer is this pencil and there is this transition when you go back this slow animation you see it's nicer of course we can do even better with the Styles and I'm sure many of you are more know knowledgeable in CSS than me you are better than me in styling I'm sure many of you I'm sure they are so if you can do better yeah please do it if you want also to share just Fork uh the GitHub repository and yeah send a pool request if you have something very nice or cool that you think would be nice to share with other people's if the design is better than mine and yeah I know there there are guys that are doing better with the design than I did uh okay what else I I in the future I have some ideas with this tutorial yeah I would like to to to to continue this this project we can do I think very cool things with this project it can really expand so I think we would love to explore more advanced features okay we can move on with more advanced stuff I think for example imagine an audio guide providing you details about each artwork as you approach them okay artwork or your designs or your links to project you know you want to showcase your project or your own portfolio it will be your personal portfolio to show to recruiters in very nice way it would be like very nice if you have a personal portfolio like that and I'm sure recruiters would love it to see it and yeah why not if someone uh is looking for a new job it will help but yeah imagine that uh we had this audio guide you move uh through the gallery you approach this projects and artworks and an audio will start playing explaining you know the project or the artwork in this case explaining van Go's art I think it would be very nice or you can add for example your voice your audio recording explaining your project this is my project I work with this company I did this and I did that and that's it now let's start with our tutorial and let's create this new features oh I forgot the most important things and yes that is the most important thing I refactored the whole code so we had the previous uh project we had like one file MJS file now I restructured and refactored the whole code it is cleaner better it is modular it has the best practices and yeah we have a file for every functionality lights walls the colliding system oh I didn't show you we will also add the colliding system you see now we cannot go through the walls you see there are some Physics like I want to use the physics engine but I thought it would be too much only for the colliding system so I used a very simple trick to do this colliding okay because there were some options do it with a physics engine like ammo JS or Canon JS do it with Ray casting also but I found an even easier solution so why do something complex when you really can do it in an easy way of course we will explore the physics I don't know if we can add like I don't know features that involves physics for this project but yeah maybe we can do it in in the future okay yeah let's start thank you for being here and please follow this tutorial okay so I want to show you the changes and the first thing that I want to show is uh some fixes for example fixing the movement someone reported that they were having problems like they had this lagging experience uh it was not smooth when they move and this is because uh this issue uh that uh someone described in the comments is because the movement isn't in sync with the frame updates every computer has different frame updates because depending on the computer how powerful etc etc so this is the issue and that's why sometimes we use uh a Delta time for this and I will show you I fixed it in this way so this is the function that is responsible for the movement and uh yeah we were like uh checking uh now it's uh the code is changed I will show you but yeah we were checking the inputs from the users what key they were pressing and based on that code number we updated and you know we moved left or right Etc now what I added here what I changed uh it seems that that movement uh is only being processed once for each key press so this is because the key down event listener is only called once per key press so the key down this one event listeners that we had previously is uh is only called once per ke press to continuously update the movement while the key is pressed okay we should separate events for key down and key up and maintain a state for the key is when being pressed okay don't be confused please because I will explain and for that okay we will use an object to track the state of the Pressed keys I created this object to hold the key pressed so Arrow up arrow down arrow left Arrow right and yeah you know w a s d so this object uh is to track the state of the Pressed keys so we will use this object here after creating uh this object what happens uh in this code that we have you see we have an event listener for key down okay and an event listener for key up we have two uh these event listeners are used to update the key press object this one we will update this key pressed object with this event listeners uh the update movement then the update movement function will be called on every frame so our function that is responsible to to handle the movement will be updated on each frame and we will use this Delta I will explain in a second okay but we will call this function in our render function so to call it on every frame which checks the state of these keys in the key pressed checks the states of these keys and moves the camera accordingly okay so this should provide a smoother and continuous movement as long as the keys are are pressed okay so I will explain we have this object to hold the keys pressed then we create this event listener key down this is when we press the keys so event listener key down key down is an event that fires when a key is pressed we pass the parameter event from and if event. key in key pressed check if the key pressed is in the key pressed object so the key we pressed the user pressed check if that key that the user pressed is in here on this object Arrow up arrow down Etc so if the user presses for example narrow down check uh if it is if this uh key pressed by the user it is on this object set the value to true if the user for example press the error right from false it will turn to True set the value to True okay if not if the key that you know the user pressed like he pressed like and I don't know another letter or doesn't matter set it to fults Like It Is by default the same for the other event listener key up in this case so event listener for when we release the key so key up is an event that fires when the key is released pass in the event parameter uh check if the same thing check if the key released this time not the key pressed but check if the key released is in this key press object this is to make you know continuously this updates not only with key down check if this is there if it is not if it is set the value to to true if it is not sell the value to false okay so if what the user is releasing is here set to true if not set to false okay now for the Delta time okay because we we discussed the Delta time one solution is to use this Delta Time by using Delta time we can Ure that the movement speed is consistent regardless of the frame rate it doesn't matter if my computer has another frame rate another computer has another frame rate so it if we have like another calculation uh I will see it differently another computer will be different because we have different frame rates so Delta time has this function by using Delta time we can ensure that this movement is consistent regardless of the frame rates and regardless of what kind kind of computer you have okay so uh there are several ways to to handle this but the easiest one and you know is using this clock from from from 3js it's a built-in okay this creates a clock to keep track of the of the time between frames between these frames so the clock keeps tracks of this time time between frames and so here in our update movement that we updated the code we create this move speed equal to five five per Delta time so move speed is the distance the camera will move in 1 second we multiply by Delta to make the movement frame rate independent you know independent from the frame rates this means that the movement will be the same regardless of the frame rate as I mentioned and this is important because uh if the frame rate is low the movement will be slow and if the frame rate is high the movement will be very fast so this is not what we want we don't want different performance in different computers we want the movement to be at the same regardless of the frame rate we want that speed we don't want like the car to move 300 kilometers per hour and in in another computer move like just slowly very slowly and then we create this variable previous position the previous position equal to camera. position. clone what is this clone the camera position before the movement so before the movement we clone the position before that Movement we clone it so this is the variable previous position we want this then we check if key pressed that error right key pressed is the object do Arrow right is this key here this property so key press. Arrow right key press. Arrow up key press. W Etc we access you know the keys inside this object if key press this error right or key press dot d it's the same because we will use error right or the letter D to move right uh controls. move right and we pass the parameter move speed okay so controls that uh we have we are using controls from here the uh okay controls it's the pointer locks that we did in the last tutorial so okay if we press uh error right or D controls. move right and we pass the move speed we want to move with that speed which is five multiplied by Delta time and the same if left or a or if Arrow up or W etc etc we move accordingly and here we will check for the Collision because uh as I said uh I added the Collision so I'm I will collide with the walls and I cannot go through break them through to the other side so I will stay in the room as you know uh as in a real Gallery we cannot pass through walls like a ghost but I will explain in a bit this check Collision but I wanted to explain this movement first so I hope you are clear with it and this update function in the end after creating the CL clock that keeps track of time between frame rates after creating the variable move speed to move at this speit multiplying by Delta time we call it in the render function you know the render function is the method that you know this will be called uh again and again and again and again these are also the animation so this is a loop and so yeah with this we are sure that we will call on on on every frame okay I hope you are clear with this I hope uh who commented about this issue and now it's fixed and I will explain now uh the Collision that I added how we did uh the Collision system it could have been very comp complex actually if we use like physics for that like ammo JS or Canon JS but yeah we could have used R casting also I choose to to use the simplest way for this because yeah why not why not so check Collision okay this I will show you in the browser in a second how it works I go back okay I cannot move anymore I go right to the wall I cannot move anymore sometimes you may find that I cannot move like you know here because maybe we are very at the limit and maybe the painting or something it's it's blocking us because yeah it recognizes as a bounding box so just move and try it yourself but yeah it works so how we did this check Collision okay here I created uh this function check collision and in this function uh we will check if the player the user will intersect with this walls or this solid things that we might have but in this case we only have walls no other obstacles and uh I create inside this function check Collision I create this variable player bounding box okay this is created with uh creating a new instance of box three so new 3. boox 3 and what is this this is to create a bounding box for the player so we have the player which is the camera we create like a bounding box for this to have it with us so that bounding box will serve as you know to find the intersection then I create a variable camer World position that it's an instance from just a Vector three this creates a vector to hold the camera position then this camera we access get World position to get the camera position and and store it in this Vector okay so we get the the camera position of this uh the camera represents the player position in this case Okay because the camera position is the player we move we with a c you know then from this player bounding box which is the Box three which is bounding box we just created I access this set from Center and size what is this and I passes parameters the camera position in the world and this vector with these coordinates so this uh set from Center and size is a method that checkes the center and size of this box okay and we set the players bounding box size and Center it in the camera position okay so basically it's just to to uh takes this and Center it and uh size it uh of the box and uh put it in the Camera World position we pass it here the parameter so it will Center on this camera position then I create uh a loop why I create this Loop for the walls we have the Wall Group we uh did this in the last tutorial that we created the walls we created a group of walls and now we look through it you know what the loop is right so w group. children because the group in three JS has the children inside so World group. children. length i++ so look through this uh children inside the wall the single wall is wall group. children I the element that is looping through iterating so is you know to get the wall the single wall is the the eye that is iterating because I is zero then I is one lies to it iterates on each wall on each children inside this group of 3jm and uh if player bounding box with this method intercepts box we pass the wall that bounding box so each wall has this bounding box okay check if the player bounding box intersects with any of the wall bounding boxes okay so if our bounding box the player intersects with this walls left front back you know all the walls bounding boxes because we have a bounding box also the wall have bounding box if it intersects return it true if not return it false so this is the function check Collision to check if the player's bounding box intersects with the bounding box of the walls around us I hope it's clear that's why I commanded every step and okay so this function where I call it I created this function to check and where I call it I call it in this update movement function where we move okay the user press keys it checks this object here if it's here return it to true so it means that we press one of those keys that is in the object we turn it to true and then if we then Al return to true we move it right with the speed that we defined here five multiply by data time okay so here in this update movement we pass this uh function check collision and here inside we have camera. position. copy and pass previous position if you remember previous position is the position of the camera before the movement so without getting confused after the movement is applied we press a key we move left or right or forward or backward after the movement is applied we check for collisions we move check for collisions do we have anything no continue moving move again move again with the speed of five multiplied by Delta time okay so we check for collision by calling this function here in the update move and check Collision move and check Collision if the Collision is detected at some points we will revert the camera to the previous position okay that is why we needed this variable here previous position and the previous position is karma. position. clone so the previous position we cloned the previous position where we were so we are here okay we are here this will be the previous position when we move so when we move that was the previous position okay I'm here I move one unit one matter forward I move one matter forward we check for collision with the function check Collision am I colliding with the wall I am not continue moving another meter forward check for Collision do I have any wall in front of me yes I have okay the check Collision finds that I'm intersecting with with with the wall what happens in the case if I find this checkol and returns that I am uh colliding return me to the previous position that we get it with this clone method okay so and that's it this resets the camer position which is the player to the previous position if I am intersecting with the wall okay and that's it uh if you just maybe might sign bit confusing I don't know maybe is just easy as it as it is but if you find a bit confusing just you know go back again just two times and I'm sure you will you will have no problems so this is for now for uh the movement update that is fixed and for the Collision this was the changes that I made for this what else I also added the checkers as you can see as you can see the checkers has like these Checkers wall texter like it's more realistic that the white material the simple material I found on internet you know here here on public you can check yourself I just put there some some textures that I found you can experiment and you know try all of this if you like another texter use whatever you want or I'm sure you can find better Checkers for the walls on internet on Google on Bing I use Bing now I don't use Google anymore but whatever uh you can use whatever you prefer and it's here let's find uh World texter if I'm not yeah World texter look at the comments that I edit okay uh yeah I will edit the at least the first time maybe we will delete it later to clean it but I will leave it because I know what it will be useful helpful for for someone so I changed here where we have the text loader. load that we explained the last time that it's the loader for the Checker uh I add this uh IMG white texture jpeg you can use you can try the others but I found this the best one from this one you know I didn't very you know deep research so you can find better texter you find it just please tell me on GitHub we can maybe change it free texter of course because yeah we we care about copyrights uh yeah you know this the world texter uh rap s equal to this repeat wrapping what is this confusing uh variable and I added the comment here W S and W T are properties of a texter that Define how the texter should be repeated in the X like left and right or you know in the y direction so we have a Tex first how we want to repeat this you know in the x axis or in the Y AIS uh these directions uh RS is the horizontal Direction the uh the X and r t is the vertical Direction the Y and this repeat wrapping that we get from three is one of the available wrapping modes and it's like you know it's the default usually wrapping mode for for chter okay so this means that the texes will be repeated in this specified Direction in this case w s which is the horizontal and again w t in you know the vertical the Y and this W texor repeat. set it sets you know to repeat uh property which is a vector two that defines how many times the texter should be repeated in this horizontal and vertical oh sorry uh directions and if we yeah if we choose uh one this means that the text will will not be repeated it will only be displayed once on the material etc etc okay so I changed also the texter here so that is for the wall texter but I want to show also something else uh another comment asked me how to rotate the paintings I'll show you here uh they have a problem they had a problem with the positioning this right and left wall paintings okay like position it uh the correct way because I suppose and they confirmed to me that they had this problem that the paintings were showing in front of us not you know so they wanted to know how to rotate these paintings that they adapt to the left and right walls I'll show you so where are our paintings yeah you see this code it's be it's becoming a bit hard to read I know you thought about it and that's why that's why I refactored the whole code and now we have like every functionality has a separate file you will see and uh I really uh advise you to follow that part a bit later I will do it later uh it took me some hours actually to to make that refactor uh but I advise you to follow because that is very important maybe one of the most important things in you know when you have a big project you need to follow this uh you know patterns and uh best practices uh make the code cleaner and modular and readable maintainable etc etc so yeah I advise you to to to check that that part later so we were in the paintings right so we want the painting where is the painting create painting here we are so in the last tutorial we had only two paintings so painting one and painting two that we pass here as a parameter to this function create painting which is here we have the image URL the width height and the position as parameters to create every chel here we created the texture the material the geometry and the mesh so basically we create this plane geometry for the paintings and every time we want to create a new painting we call this function create painting So painting one equal to create painting and we pass this parameters here custom parameters as we wish so I pass this zero J back the width 10 five height and this Vector three for the coordinates in X X Y and Z for the painting two the same thing uh now for the painting three and painting four for the left and the uh for the right and the left walls that was this issue of this plane in front of us instead of adapting to to to the wall so what I did here to fix that uh small issue so painting through here the same thing we pass the image URL we pass the width we pass the height the coordinates for the vector three X Y and Z and here uh to fix it we rotate this painting and in this case so painting three rotation. y we rotate on the y axis math. Pi ided by 2 and we mentioned math. Pi in previous tutorials if you remember but if you don't remember math. Pi is 180 Dees okay so this is degrees in radians so math that Pi is 180° is half half the circle okay so math. Pi / 2 is 19° so I left the comment is if we don't rotate this it will show up in the front of us instead of line correctly on the wall okay this is the small fix small trick uh the same for painting four but the only thing the difference is that it's negative here okay so the same as above but negative just negative for for the other wall and yeah I also add added the the walls for the walls the paintings for the back wall so Al no I added two in the right wall two in the left wall and two at the back wall and that's why we have in total eight eight uh paintings and here you will see the same thing for the painting I8 which is the painting in the back wall I rotated it 180 degrees in the y axis because if I don't do that we cannot see the paintings from behind it like we if we if we see it here like we have the painting of the back wall so this is the palm of my hand is the painting if I am here I can see the painting but if I am here I cannot see anything I will not see it will be the texture will be visible only from if we have it in front of us okay so if I have the the painting here I will rotate it 180° to be able to see it okay this you could have run in this small bug if you did it yourself so yeah this is and these are some of the changes uh for the menu that you see a small animation and other things I'm not going to make the tutorial for that for CSS because we are not here you know to make a tutorial for about CSS but for 3js and 3D programming so but you will find this uh Styles in the CSS file here copy everything if you want to check how I did it Etc you can check you can check uh here because I dided some you know I added some key frames for the animations so it's interesting maybe for for someone so check here and copy it's in the GitHub or something else I had like a comment I uh on my GitHub uh someone opened an issue in the repository on GitHub because they were were having a problem with a project so the problem was that they were trying to make the project go live by you know clicking this go live here or you know usually how you do with HTML uh open on live server you know on HTML they open on live open with live server so open with live server but this doesn't work like that uh in the last last tutorial I think I didn't mention this so sorry if I didn't mention I think I did I don't remember but yeah to run the the project every time when you are on the GitHub repository click the button the green button there which is uh can I find just a second just a second let me do I have it here I'll show you I updated also the RM file so you have it everything explained here okay so we have everything explained here of course the first thing first uh you need uh okay download it here you see this green button code you can clone it with Git clone and pass this URL here so create a folder open the terminal and G clone URL or just download zip and open with visual Visual Studio okay I remember someone like corrected me like for the wrong spelling because I say visual but yeah Visual Studio whatever and uh G clone or download zip after you have this project on your computer of course you need no JS you should know this but yeah if you don't know you need no JS environment because JavaScript will run on the browsers supported by you know the browsers but locally we need nodejs to have the environment to be able to run JavaScript because not JS it's not a programming language okay uh of course you need Visual Studio here are the links to download and then after cloning or download the zip here clone or download you in the root in the root folder just run mpmi or mpm in it will install the not modules all the dependencies this big guy here this not modules that has like you know it's heavy as a black hole so it will install this I think because we as we said I mentioned we never never post this on GitHub they are too heavy uh after installing the dependencies we run CD SRC here okay stop the server okay from the beginning as let's say I'm from the beginning I have the git bar so I usually do p WD to to check the path but uh you can do uh CD if you don't use G bash but you use Powershell you use CD it will show the path I do PWD to check the path and I am on SRC folder okay I did CD uh dot dot to go back One Directory so now I am you know at the this 3D art gallery the root folder here you do mpm install or mpm I after installing the not modules you run CD SRC with CD SRC you go inside this SRC folder here because it's here that you should run the next command to run the project live look I'm here now on SRC you see and here just npx Vite run Vite which is the build tool we use to run our project locally okay our local server MPX V that's in just a second less than a second you will see this address here local or press h for help but just click here and you have the project live okay if you need help for you know press h r to restart the server uh you to show server URL o to opening browser C to clear the console yeah you clear everything and uh yeah and Q to to quit just to quit okay it stopped so you need to run it again if you stop V is very nice V is very nice now I only use V I don't want to see anymore create react up for example for those of you who use cact up I think is is going to die and I think it's is dying no I don't know if anybody uses anymore um I think neither is his creator likes it anymore but yeah V is very very cool it's the creator of Vue vuejs that uh created and I love VI by the way lately I'm not using react but I'm using view for my work and also whatever so this is the problem that someone opened an issue on GitHub for this so keep in mind node.js you need the editor of course after installing nodejs and nodejs is pretty straightforward to just download install it will do automatically uh open on vs code and you know follow these steps that we just uh mentioned okay for now is this uh The Next Step will be to to refect Factor this whole code okay and we will create file for every functionality okay it will have uh it's not so simple because yeah it's a mass with a big uh very long code and so I advise you to follow this part too okay I will do it in a second Maybe I will go and you know drink a glass of of water because yeah I'm talking too much okay now I will show you how to create the info card so the feature here that we get close to the artworks and we show the information so it's a nice feature to have not only for this project but also for other projects that you might create in the future so it would be good to to to learn it let's get back to our code and here as you can see there is a lot of changes because as I said I I refactored all the code and now we have this structured folders you see for every functionality we have a separate file and it's very clean now you see now this is our main JS it was like 500 600 uh lines of code before I refactored and now is just you know some line of codes and everything is uh cleaner I will explain this later but for now I just want to to to show you how I did the info card and then I will I will show you more in detail about the refactoring okay so for the info card I created a separate file because okay after refactoring the code I created everything like you see bounding box saling event listeners floor lighting menu movement painting data painting GI paintings rendering scene etc etc etc so for the info card is this component here this module painting info okay and uh here in painting gifo I create two two functions display painting info and hide painting info one function is to display and one one is responsible to to hide the card so this function first of all we create a variable info element and this variable is just to you know to get the reference to to the Dom to this element with ID painting info which is this one here in the in the HTML so this ID here we get a reference to this because inside here we want to create you know that element to show or hide so after creating this info element uh we set the content inside and to create the content inside this is Javascript it's nothing to do with 3js is vanilia Javascript vanilia van you know JavaScript plain JavaScript uh to create content inside we use inner HTML so info element. inner HTML equal to first we create a title and this title is from info. title and this info is an argument passed here I will explain that where we get it from so info. title uh info. artist info. description and the year okay so we have this element here and to display we use this class list. add and the class show this is to show to to add the the the class show here so to this element here we had the class show because we want to point to that later the same thing with this function hide painting info we create this info element to get the reference to that ID painting info and then we just remove the class show so here we have this class show and here we remove this class show and that's it two functions hide and display then when when we will use this and where here in the rendering as you can see now this rendering is now extracted here in a separate file but this was you remember in the last part of MJS there was the function render which is you know uh the animate uh function to Loop and render the scene and do the other stuff that will okay render on every frame because yeah in this render we call this request animation frame which calls the random function again so it runs over and over and over so this is the function to render things but yeah I refactored so it's not in MJS it's everything here so I import three here I import this displayed painting info and height P painting info from painting info JS this one that we were exploring together to export this functions from one module to another module again this is Javascript uh you add this export at the at the start okay so export function display function etc etc you can also make it an nrow function like export con display info equal okay so now now this is an nrow function yeah we can make it like that even here export const hide painting info equal error function okay as you prefer it's the same thing just you know this is more modern real function okay so to export functions you add this export here at the beginning and then uh if you there is also export default usually when you have only one uh component that you want to use you do the export default Etc but here export con is just when you have in one file different functions that you want to export this is another topic but yeah in basically you just add this export and you can export it in another file so here Import in this case you need to add the brackets here if you export it like this if if it was export default it will be without brackets again this is a another topic you can uh research more about this ways to you know to export modules in 3js U sorry in JavaScript because this is plain JavaScript but yeah we export these two functions okay to use it here and in this uh uh render function okay you remember again this is function we can again convert it into an nrow function it's not a problem it's the same thing uh in this render function which calls itself in a recursive it's a recursive call with this request animation frame again and again here what we do after we pass this update movement you remember the function update movement which was in main JS but again I will explain all this later but for now just focus on this uh feature to display the info card so we call this update info here in the render function uh we create first of all we create a distance three sh equal to eight it's like eight units or eight meters in this case Okay so this distance three sh is the distance that will be from us the user the player and the the painting the artwork as you prefer saying painting or artwork so it's the distance why we want this distance we want because at a certain distance we want to display or hide that painting so we need a variable to to store the distance then we create this let because it will you know it will not be a constant it will change we will use it you know this conl in JavaScript no need for for that so we create this painting to show what is this this is the varable which is responsible uh to store a value in which we want to show the painting or we want to not show show the painting uh explaining it a bit in detail I will show you the code here we have these paintings okay don't worry much about how we get now these paintings in this new refractor code but these paintings you know we get it as an argument uh we passed it here for this setup rendering I will explain it later but for now we Loop through this paintings okay paintings that for each and uh then we create a distance to painting and to get the distance to this painting from the camera to the painting because the player remember the player is the camera so we are the camera that we move as you know the player the player the the user so to get the distance from us to the painting we use camera which we are the user that position and we use this method here distance two and distance two we pass a parameter which is the object that we want to get the distance two and the object is the painting we want the distance to the painting so the parameter will be this painting. position get distance from the painting okay and we store it in this variable distance to painting simple as that now we create an N statement to check if distance to painting this one we get the distance that can be be one 2 three depending how far it is if this distance is less this than distance three should this variable here which is eight so if the distance from us and the painting is less than eight okay then the painting will be showed so the painting will be stored in this variable painting to show that's why we created it okay like a way to you know to know so set painting to show to to our painting okay in this case the painting will show we we have that value and then how we will use this logic here that we set the painting to painting to show if painting to show like if this is true okay so if there is a painting there to show because if this is true so it means that uh we are less than 8 m from the painting So if this is true and we are less than 8 mters call this function display painting info which is this function here that we imported from this file which creates this H uh HTML elements okay so if painting to show is true call this function and pass inside painting to show. user data. info and this is an object from painting data okay so painting to show user data doino because this user data here we will get it from the painting so each painting you know so we'll have a user data and an info I will explain this on how I refactor the code but yeah at the moment you just need to know this display painting info and pass you know the info of that painting or else if this painting to show is not true hide the painting info so do not show okay and that's it this is we have this HTML here HTML element and we have the styles for this painting info I added the Styles you know some transition I add it at the top etc etc you can find these styles on GitHub okay and that's it this way we can display the info card okay for each painting the painting changes and the info card of course changes that that's it okay guys now I will explain um the refactored code so as you can see I have many files now and the MJS is cleaner so let's see these are the Imports okay so first of all we import everything from three as usually then we import scene and setup scene from CJs okay and then CJs here okay then we EXT uh uh get this these variables from the setup scene let's take a look at this uh scene and it is on this files scene scene okay here okay so I extracted all the logic and the code for the scene in a separate file okay so basically we import uh everything as three then we import the pointer locks we create this uh scene here as usually create a new instance of three sin this is the same code but with a difference that we have a function we create a function for that code that we had on Main js on MJS we had like the camera the render controls and everything the same thing okay but we create a function that we can export this is the difference okay so get that code and create a function which can be export okay and that's it so I added some detailed comments you can read and I think they will be useful if you forget something for example you can see the code and check the comments okay so you create the function and you can export it in other modules okay so here there is pretty much the same code that we had on on MJS it's just that we export it now here I don't know if I changed anything here but yeah the main thing is that we declare this variables camera controls and renderer and I return them here I return the camera controls and render so that we can use them in the other modules so this function returns this camera controls and renderer so we can use it in the other modules okay so we get the scene here uh okay as you can see now we can get this uh camera controls and render here that we were returning from setup scene function okay this is just a simple texter loader to load the texter and we need it here because we are using it here as a as an argument so then we have the walls we also extracted the code for the wallts in this create walls function which is imported from Walts do. JS as you can see let's take a look so wjs the same thing we need the three here because okay and we create a function which can be exported the same thing so this fun function takes two parameters scene and texture loader because yeah we need scene when we add things see that add for example and the texter loader because yeah we need the Checker loader to create the checkers and yeah this is there are also comments everywhere here and uh yeah as you can see this function Returns the Wall Group so the wall group is the group that has all the walls front back left and right so this function will return this wall group and we can use it in the other modules as we are using it here to render the walls in the scene because the main JS is the primary let's say file to render everything the main JS has modules that we need to render all the same okay so for the walls we have it here we create this variable even though we it's yeah we use it here but we create this variable and call this create walls which takes the scene and checks the loader so this is uh the beauty of functional programming because if you see here this gr walls takes two parameters okay scene and text to loader so how we get this scene because I don't have the scene here I don't have the scene here so we get it when we call it here when we call it here we also pass it here so SE here I get it from this scene from scjs so I import the scene from sjs here on MJS I pass it here as a an argument and then in the wals JS I can use this here can see I use it in this cind just to add this whole group basically I needed yeah just to add this but I don't have this scene here so I need to to to get it from Main JS which is also uh taken from this uh you know CJs okay and that's is that's it for the walls the same thing for the floor we import this function setup floor for floor JS and and it's uh Flor JS okay Flor JS the same thing import three because we will use it create this uh function that we can export and again the scene is passed in MJS where this setup floor is called so we don't have the scene here use it but in MJS when we call this function setup floor we pass the scene from yeah the CJs okay you see the beauty of functional programming it's the code is cleaner of course and yeah uh for the texter loader uh I just create a new from three because I can create it from three or I could pass it you know but I create a new tter loader and yeah the same thing and this does it return now this just adds the floor to the scene that's why I needed this just adds the floor to the scene and when we will call it here on MJS it will render the floor the same thing for the sailing you see how clean it is like this way and we can control and we can maintain the project better we can read it better if someone else uh wants to work with this project they can read it it's more readable and it's uh more maintainable and also for where are we okay sailing for we explained the lighting okay let's yeah let's start with yeah with paintings or lightings because yeah painting is a bit more complex so lighting we create this function set up lighting which takes scene and paintings as parameters that yeah we will pass it here on Main JS always this is the logic paintings we get it from create paintings from painting JS and we pass it here we create the ambient light and the spotlight we did this in the old tutorials we set up this settings for the spotlights and we return the spotlight here to create the spotlight uh we use this Spotlight and create like one two three and four with this coordinates okay and we add it to the scene the spotlight and also the other spotlights and that's why we needed the scene here and that is for the lighting then we have paintings we use this create paintings from paintings JS find it here so to create this uh you know we extracted that code for paintings that we had the function create paintings also in main JS and now we will use also the painting data which is another separated file painting data which has the data for you know know all the paintings we have info object here etc etc the image SRC width and height so this array. from if you don't know creates an array from an array like object the first parameter is the array like object the second parameter is a map function uh this creates like uh an array of four because we we we will render like uh four paintings for a wall four four four and four at the back the map function chases two parameters one is the element and one is the index the map function Returns the value that will be added to the new array okay so this map will return the value that will will be added to to the new array in this case we are returning an object with a painting data so we have the painting data here uh this is just a placeholder for the element we are not using and we yeah we don't need it at the moment and I is the index and we use it to set the painting number and since you know we had like plus one because uh yeah the index starts at zero as you know for the arrays so 0 + one but just don't get confused of this you can take a look yourself find it on GitHub so yeah it's just you know we can we can change this actually I will change it because I I will let like description for each each artwork so I will change this I just wanted to make it quickly you know four paintings for each wall just to set the position but we will change this all don't mind too much but this is the idea we import this painting data for from this painting data JS we create this function create paintings which takes scene and textor loader that again uh this arguments will be passed from Main JS where this create paintings is called here create paintings is called we pass scene and text the loader we create first of all a variable which stores an empty array this will be the array of paintings then we Loop through the painting data that we get from this file that we we already seen then we create a mesch for each painting like we create you know a 3D object for each painting and the 3D object is a mesh and the mesh is a combination of geometry and material as you already know by now then we set the position of the painting and the rotation of the painting then we add a user data property to the painting that will hold the painting info okay information so painting that user data we create this type of painting we just need this uh so we can check if the object is a painting or not so it's a type of painting and the info we add data. info we add the painting info to this user data object and data is the current painting object in the for Loop okay is the is the painting object we are iterating in this uh loop and info is a property of the painting object that holds the painting information and we saw that we have we have the information here for for each painting yeah then painting uh that cast Shadow true to set the painting to cast The Shadow and receive Shadow to set the painting to receive the shadow then in the end we push the painting to this array of paintings okay so we have the paintings there and we return this paintings okay we return this array of paintings so we have the paintings in this array that we can use later so here here we call this create paintings we create this variable paintings which calls you know it's assigned to this function and we can use them later the paintings which is needed here in the Bing box that we will check and also in setup rendering that we will check to is used here as a parameter you see like uh how nice it like this way it's different but it's way cleaner and also maintainable and yeah the lighting we have the bounding boxes we have the setup plate bottom oh yeah let's check the bounding boxes which which checks the walls and the paintings you see is to create the bounding boxes for the walls and also for the paintings uh we need this because we use the Collision you remember so for the Collision we used these bounding boxes that we checked if they intersects with with a player bounding box okay so we have this file here bounding box yeah we import three from three then we we create this create bounding boxes function which chees these objects and what is happening here we have also this condition if array that is array this like uh the contrary that it's like it it turns from True to false so if it's not uh an array and in this case we we check if the object if the object is an array or not if it's not we will assume that this is a 3js group it's not an array in that case if it's a 3js group if this is not an array we set objects to objects. children because we assume this is a 3js group and I will explain it more in detail here because in 3js a three group is a type of object used to create like you know parent child relationship between objects so there is a parent and then there are you know the children and uh yeah in this uh group in other words a group is an object that can contain other object in inside that's it and we we want sometimes this group because we can manipulate several objects at a time as one okay so the children property uh of the group of three group is the n array that contains all the objects okay so the child objects inside that are part of of of this group so when we add an object to a group uh with group. ADD as we added the walls wall group. add front wall uh back wall left wall and right wall we can access that object with group. children so we can access them uh when we need so in our code the create walls returns a group for the walls you remember we have the function create walls it it returns a group that contains several wall objects and when we pass this group to this create bounding boxes because this create bounding boxes will be used to create bounding boxes for the walls and for the paintings but the walls are three group the paintings are an array so this function here to check the objects parameter an array and also a three group grp we did it like this with this conditional okay I hope it's clear but yeah uh we when we pass this uh objects here to this function create bounding box uh we want to create a bounding box for each wall in the three group and to do that for the walls that are group we need to Loop over all the children all the children array of this group so when we call create bounding box walls here create bounding box walls the object's parameter of this function is a group objects so for the walls when we call it it's a group object and yeah we need to in order to to Loop over this wall in the group we need to set objects to objects. Children okay I I know it may sign a bit confusing but basically we are using this uh create bounding boxes for the walls which are group and for the paintings which are an array if they are group we need to to set this to the objects we need to set to objects. Children which is then the array of of objects wall objects uh so this was when uh this object objects were a group like the walls what what about when they are an array as for the paintings in that case like uh create paintings that we had in paintings paintings are an array here as you can see and in that case uh since create paintings returns an array and not three group The object's parameter this one objects is in Array so we don't need to do anything in that case as I explain in the comments uh below so for that reason that's why we start this function by checking if it's not an array if object is not an ARR assumes that it's a group and sets objects to objects uh if object is already an array it skips this this step so if it is an array and not a group it will skip this step and in that case we Loop through objects which is an array and we set you know a bounding box for each object then object. bounding box set from object which set the bounding box to that object which is you know the object iterated each object yeah maybe I didn't explain very well this part but yeah you can read the comments and I'm sure you will get it because yeah I commented this whole thing here and you will get it this is just because we are using the create bounding boxes here function to pass the walls and to pass the paintings and they are different one is a group a three group and one is an array and we need this check uh we have this add objects to scene which takes scene and paintings what is that we have this in scene helper JS is this just this piece of code here this function will take the scene and an array of objects which can be passed dynamically uh we choose and add each object to the scene so it will uh loop objects that for each at each object okay so this is just function an helper function to add each object to the scene why we need this we need it for the paintings as you can see we call this paintings here with create paintings we created the paintings we return the paintings the paintings array we return this paintings okay we created and we returns this paintings but we need to everything should be added to the scene as you know by now and with this helper function add objects to the scene we can add this paintings okay and that's it then we have setup play button you see that in on Main JS pretty much we see everything that we have so we see what we have here it's very readable even for someone else that just opened our project and they want to take a look and understand the code they see here on MJS everything and yeah they can understand and redirect it to this functions and modules so we have set to PL button and the file here set up plate button is from menu JS and this is for the menu to show or hide the menu okay ask show and hide the menu that's it okay so we had this hide menu and show menu you already know this functions because you had it on Main JS I just extracted the logic with just uh added this export to export it also the start experience you already know also for the play button which just gets a reference to this play button in HTML with ID play button this one then adds a click event listener to the play button to start you know the experience and that's it we have also the menual logic here separated uh this play button as we saw is uh exported to main JS and it we pass the controls to it here because we don't have the controls you see the functional programming we don't have the controls on this file on this module so we call this function here and we pass it from you know from here from njs because we get it here we get it from setup scene okay so we import the setup scene from scjs importing the setup scene we the structure this uh variables for camera controls and renderer that we get from setup C and then we pass it we pass this controls also here on setup play button and then we use it here on menu JS that's it the logic what else we have we have setup event listeners that again it takes controls as a parameter set up event listeners okay here and this is the logic and the code for the functions on key down and on key up the object uh key pressed that remember we we created in the last tutorial is from this movement uh file which is a separate uh file movement here uh we have this key press which is uh okay exports const key press so we can export this and we import it here from Movement we also import this show menu from menu JS that we already saw and we add uh the controls parameter which is the pointer lock controls and this path on Main JS here setup event listener we pass controls that we get from setup scene okay the same logic you see the beauty of functional programming and then we add the the event listeners uh to the document which is the whole page so we have key down uh we have key up and unlock okay so key down is the uh the event when the key is pressed okay key up is when the key is released and yeah unlock is when the pointer is unlocked so here we we add an event listen to the controls to show the menu when the pointer is locked show the menu okay we already did this part for these functions uh the event is the object that has the key property so ev. key in key pressed check if the key pressed by the user is in this key pressed object if yes we will set the value to to true so if the user presses Arrow up we will set this false to true if the user presses error right we will set this to true and so on okay if the user if you know the key that the user presses is is is not we will set it to fals as it is by default when the key is released for the on key up so the same as for key down we set to false when the key is released so if the key is in this key press object we set it to false when the key is released so the user releases the key we set it to false if it's already true okay this is for the event listeners we have this movement uh yeah that we we did in this tutorial that we fixed and updated for smoother experience so yeah I added some comments here details comments so you can read for everything but yeah just to make a recap we have this update movement always exported it takes Delta controls camera and walls okay uh we get these parameters from setup rendering where this function update movement is called and if you see here in rendering doj we have this function setup rendering okay you see these parameters okay so we take them from this setup rendering and setup rendering gets the parameters from Main JS this setup rendering gets these parameters from MJS because it's here setup rendering because yeah we get it from setup here because a bit movement is called here in the yeah in this rendering JS okay you see it takes this parameters here when where we call it parameters we get from setup rendering above from this which gets from MJS as we as we said this move speed is five multipli by by Delta time move speed is the distance the camera will move in one second we multiply by Delta Delta to make the movement frame rate independent or you know the frame rates this means that the movement will be the same regardless of of uh the frame rate that each computer might be different and this is important because the frame rate is low the movement will be slow and if the frame rate is high the movement will be fast this is not what we want we want the movement to to be the same regardless of the frame rate okay we have this previous position which is equal to camera. position. clone we clone the camera position and store it in this previous position okay because we will use this to rest the camera when we check the Collision so this previous position is the position before uh before we we we move so if we collide with the wall we will reset this position to the previous position so check the the keys that the user is is is press this code is self explanatory if we press error right or D move right and we pass the speed of this speed and then we check for the Collision after the movement is applied we check for collision by calling this function check Collision which checks these parameters of camera and walls and if a collision is detected we rever the Karma's position to its previous position okay so it cannot move through through the wall preventing the player yeah to to go through uh yeah if check Collision uh ca. position. copy previous position someone might ask here why uh position copy and not set position okay this we rest the ca to previous uh we use copy instead of set because set will set the position to the same object so if we change the previous position the camera Position will also change copy creates a new object and uh with the same values as the previous position so that's why it's this different so don't use set but use copy here to the previous position okay so we export this check Collision because we need it check Collision checks the camera and the walls as parameters and returns true if there is a collision okay and false if there is not a collision the camera parameter is the camera object and the walls parameter is The Walls Group not array the parameter are passed from update movement function where check Collision is called okay we have this update movement that has these parameters and we get this from there because we call this check Collision inside update movement uh and update movement gets the parameters from setup rendering where it is called so we get check Collision parameters from this update movement and update movement gets this parameter from setup rendering where update movement is called and setup rendering gets the parameters from Main Js you see setup rendering gets these parameters camera Etc from MJS because we are importing them here from the files and this is the logic uh so we check uh we create this and Export this check Collision we inside this function what happened uh we for recap we create a player bounding box which is an instance of three box three that creates bounding box for this player or user we create a variable for the camera World position which again is an instance of three Vector 3 class and it creates a vector to hold the camera's World position then we access this get World position method from with a camera camera that get World position and we pass Camera World position here is Vector three and this gets the camera's World position and store it in this uh Camera World position uh you know that the camera represents always the user the player uh in in our case then this player bounding box access this set from Center and size method and this sets the player bounding box to the camera's World position and size the size here is one one one because the camera is a single point this set from Center and size method takes two parameters so the center which is the ca word position and the size which is this Vector three okay the center is a vector uh Vector three that represents the center of the bounding box the size is also a vector three that represents the size of the the bounding box yeah the size is the distance from the center to the edge of the bounding box in each Direction so the size is 11 one the bounding box will be two units wide so 111 and the two units tall and two units deep if the size is 2 to2 the bounding box will be four units wide four units tall and four units deep Etc you can read more here if you forget or if you need again and yeah we create uh this Loop to Loop through the children uh of of the walls we Loop through each wall and we get the wall and then if the player bounding box intersects with this walls bounding box with this method intersects box and we pass the walls bounding box so it's like the code is self-explanatory and this naming is very clear so if the player Bound in box intersects with the walls bounding box okay return true if not if they doesn't uh intersect return false okay and that's it for the check Collision uh function and that's it I think we covered everything and set up rendering two set up rendering which is in the rendering rendering okay here the rendering is you know if you remember the last part of the code in the end we had this rendering function which in a recursive uh does a recursive call and uh it calls again and again in makes a loop so yeah we pass this parameters which we get from Main JS we create this clock from the buil-in 3. clock it it keeps track for the time between uh the frames and yeah we create this render we extract it from MJS we have the variable that we need Delta because as we mentioned the for the Delta which is clock. get Delta basically 3. clock. getet Delta and this Returns the time in seconds since the last frame uh then we have this update movement to update uh the movement which checks these parameters Delta controls camera and walls that we you know we explained before explaining the update movement function we create this variable distance three sh and set it to eight for example or you choose to set the distance from the player and the painting okay because we need this distance to create the the the logic for the info card so if we are closer than this distance we want to show the info if we are you know away than 8 m we don't want to show the info card we hide it okay so we also create this painting to show variables and we will see why we need it we take this paintings that that we pass here as an argument that we check from create paintings uh function we Loop through all the paintings which was an array remember that we discussed before we Loop through all the paintings and this distance to paintings uh variable will be the camera that position that distance to the paintings is self-explanatory we get the distance to the painting okay so this variable here is to get the distance to the painting how far is this painting because we have this three should of eight units eight meters so we get this with this method distance two and pass the painting position and then if this distance to painting is less than 8 8 m is less than distance three should so if we are like uh 7 m away from the painting we set this painting to show that we created here to painting this sets painting to show to this painting which is lesser than eight okay in this case we know that the painting will show we will use this this with this value because we know that in this case painting to show is set to this painting which is lesser than eight units so we will show the painting and here we see if painting to show if this is true and we are less than eight we are closer to to to the artwork display the pl the painting info if not hide the painting info and this to display as uh we saw already we get it from this display uh painting info and hide painting info which is from painting info. JS here okay display display place this element and hide just removes the class show and display adds this class show because uh yeah to this element with ID painting info we add the class show when we want to show the painting we remove the class show when we want to hide because we have this in Styles in the end you will see we have a style for the painting info show so painting info. show for the class of show we apply these Styles and we remove our ad and we have the other Styles as well and and that's it I think we covered everything yeah I think we covered everything so this is the refactor I think you like it more like this yeah leave me your thoughts what do you think about it and this is for this tutorial uh let's finish here thank you for following this and uh see you welcome back developers and 3D design enthusiasts today we are journeying further into the world of 3js as we continue building our 3D art gallery first of all you can see that we have brand new textures and they are in 4K resolution for the best quality and yeah the difference is visible I think it's much much better now I have added the new ceiling the walls and I really like the floor there are details and the quality is good then we have integrated the pointer lock controls toggle so now you can see seamlessly toogle between game mode giving you smooth navigation around the gallery and also the UI interaction mode letting you interact with on screen elements at is as you can see I press the space key and the poter lock controls are disabled so now I can use the mouse S I can click and you see I'm redirected to my landing page to my shop or wherever you want the user to be redirected this is the picture that some people asked for it in the comments so I edited but yeah you whoever wanted to touch the the artwork in the gallery but you had that do not touch sign and that stopped you right well now you will be able to interact with the paintings you can touch and you can click so you can do whatever you want you can uh attach other event listeners you can add your own logic but for now I added the logic to Simply navigate to an external website which will be our website but feel free to to make your your own logic about it it's easy customizable now so you can do it uh what else else uh if that's not exciting enough for this part six uh we have introduced also a VR button for VR support you can see we have the enter VR here this is also a feature that uh someone requested me by writing me on private so I couldn't uh make it sooner and I'm sorry for that because yeah uh that's someone that wrote To Me wanted to beat you know he had this project and really needed this feature but I was very busy but in the end yeah I at least started this feature to implement it so now we have this enter VR and we need to install an extension for this because I don't have a VR device and of course I cannot test it because I would need a VR device or headsets but but uh if you don't have it but you want to implement this you can download an extension on Google Chrome and that extension is called I think webxr simulator webxr simulator yeah yes it's this one install it and then go to your project open the the developer tools and here you should find this web Pixar open it and you can see now that we have the simulator and we can choose for example we have here Oculus Quest or Oculus go Etc Google Samsung Galaxy but yeah leave it here Oculus Quest and if we press enter VR you see that the scene turns black of course I cannot test it because I don't have the headsets but it shows that it works and if we go to the console you see web XR session started because I console log this so it means that it works we will go further into this and we will explore it together but follow me on this part six all right let's Dive Right In now we'll be adding an audio guide feature to our 3D art gallery this is an awesome feature that you could use to explain your projects or simply to guide users through your gallery and for this let's start by setting up some basic control controls for our audio guide in our HTML here we will need a div uh with a class of audio controls and two buttons one to start the audio and one to stop the audio so the shortcut for that audio controls and two buttons shortcut again for bottom bottom start audio okay we have this basic controls for this now let's switch to our JavaScript and we are going to create a module called audio guide where we will handle the audio functionality so create a new module here call it audio guide and as always we import three from three okay in this first line we will import the three as we always needed and we will declare a variable sound this variable will be our audio Source okay so we need an audio Source this audio Source will be this variable let sound after having this audio Source variable what we need we need the function that will make this possible and let's call it setup audio and since we needed to exported it would be export const setup outo okay so narrow function because we will need everything here inside so we have this uh setup audio uh this setup audio will will check as a parameter the camera because we need this camera parameter I will explain everything no worse so the first thing is for the audio um like in real life we have the music uh to be able to listen to the music we need our ears right so we listen to the music with we need some ears and the same thing in 3js we need this listener that will be will act as our ears okay so a variable for that const listener we are not going to call it ears so yeah listener and this uh we will get it from the audio listener uh class from three so new three do audio listener it is oh no it is it parenthesis okay uh make sure you are writing inside this function okay because when we will export it this logic will be inside this setup audio not outside because you will get errors ex ex so we defined our first function and the only one that we will need actually this takes the camera as a parameter and now inside this function we will create an instance of this three audio listener that as we said is essentially our ears to listen to to to the audio and the last thing is uh this listener will be added to the camera because let me explain camera. at we pass the listen this means that as the camera moves the sound will change accordingly creating a realistic audio experience okay that's why we attach this listen to the cover after that what we need we will need uh to create a new object which is 3. audio to pass our listener this will represent the audio Source in our scene let me explain we have this variable that we created and we said that this will be our audio source so sound equal to new 3. audio and to this audio we pass the listener okay this will represent the audio Source now what we need we need to instantiate AIO loader which will allow us to load our audio file because yeah we need to load the file and to load the file that we will download and put it somewhere in our project to load this file we need a loader and this loader is from three audio loader and that's it we will create uh for this const const AIO a loader and this audio loader as we said will be instantiated from three. audio loader it is here audio loader parenthesis don't forget now that we have this audio loader we are calling the load method and we will pass the file path where we have uh this sound this audio and we will also have another parameter apart from the file and I will explain while writing it down audio loader. load pass the file path here that can be yeah we will add the folder sounds inside this folder sounds eventually will be the name of of the the audio let's rename our audio audio guide because maybe we will have more than one audio so that OG you know the format OG and here as I said inside this oh I'm outside okay inside we we will also pass a callback function and this callback function will run once the audio file is loaded so function that we will run once the audio file is loaded we will pass here the buffer y because because here we will set the buffer of our sound object to the loaded audio data and the nameing in 3js is always intuitive so we we use this uh methods that the naming can explain itself so sound our sound set buffer and we just pass the buffer that I pass it here as a parameter also this callback that uh will run once the audio file is loaded we will set the buffer but also we want to to to enable looping because yeah for example I want to add the background music at the moment and I want just to to Loop it uh the same thing the naming is uh self-explanatory of this method so sound. set loop and you set it to True simple as that also you might want to to adjust the volume sound. set volume and from a range from 0 to one you can choose 0.5 okay make sure everything is inside the curly brackets of this setup audio now that we have this sound and we created the loader we need uh two functions and we create the start audio the function to start the audio that we will call it and also a function to stop the audio and these two functions are pretty straightforward okay so export con start audio in this case to follow the logic uh when you create things when you create functions in programming you want that if there is a if there is a sound you want to play it but you want to check if there is a sound play it then if it's currently plain then pause it okay this is the logic because you you had the sound okay now you just want to start or stop it export cost yeah yeah yeah it's inside let's put it outside it's a separate function as I said it's pretty straightforward is there is a if there is a sound if sound if true just play it for that sound that play simple as that the same logic for stop audio export const stop audio if sound if it's currently playing you want to to stop it it's the the same thing not stop but pause so sound. pause okay yeah and that's it the last thing that we need finally we will import this setup audio function we will import it to our main JS okay we call it so we have the audio in our SC so go to main J s import this setup audio okay it's uh not an a default export so don't forget the curly brackets you know that I know from audio guide and then just call it here in MJS set up audio and you pass the camera as a parameter yeah you are passing the camera because you are using it here in the audio guide file you see you are using the camera that you attached The Listener to the camera to be able you know to to create that uh 3D experience as you move in the scene but you don't have any camera here defined in this file JavaScript doesn't know anything about this camera so yeah you have the camera here because you are getting it from setup scene and that's why you pass it here to use it also here and that's it we now have a working audio guide I don't think we have any errors oh okay I need to restart it you see here start audio guide stop audio guide yeah I need to put the audio file in my project because I don't have it but yeah we should not have any problem we will test let me add the file okay guys before we continue with the new functionality of the pointer lock controls to enable or disable them when we press a key I just want to add a small fix for the audio guide file because sometimes you may have some issues on playing the audio okay you will wait for it and it will not play immediately and this is due to the asynchronous nature of audio loading in JavaScript and how the web audio API handles playback requests and here is an adjusted version of this audio guide file that maybe should work more reliably there are just a few lines of code really so we create first a new variable and this variable will be called buffer loaded and by default it will be false okay this flag is to track if audio buffer is loaded or not and here when we are using this load method when we are are setting the buffer and setting the loop here we will set the buffer loaded to true this will set buffer loaded flag to True once the audio buffer is loaded because yeah we are using it we are loading the sound here we are setting the buffer setting the loop volume and also the buffer loaded it will be true and why because here when we are starting the audio and here we have the condition if sound is true so if there is a sound we will add and so if sound but also buffer loaded true so if there is a sound and if the buffer loaded is true so check if the buffer loaded before playing then sound. playay and that's it this is the fix and that's all it should be better now for the asynchronous nature of JavaScript in this version buffer loaded is a flag that tracks whether the audio buff buffer is loaded we only allow the audio to be played if the buffer is loaded okay so that's why we said buffer loaded to true this approach ensures that we don't attempt to play the audio before it's ready which can cause issues or inconsistencies however please know that it may still take some time to load the audio data especially for large files or slow network connections dur in which the audio cannot be played so keep in mind that all right let's continue fixing the pointer lock controls now and here we should go to the file event listeners because here is where we will make the changes for the pointer locks at the top we will introduce a new variable lock pointer which will keep track of the state of the pointer lock okay if it's true it means that the pointer is locked and we are in the game mode if it's false it means that the pointer is unlocked we can interact with the UI elements okay so let's introduce this new variable and follow me step by step so let uh lock pointer and by default it will be true and also another variable for the menu to show it uh when it's unlock or not so let show menu unlock and this by default is fult so these two new variables lock pointer and show menu unlock lock pointer will help us know the current state of the pointer whether it is locked or not simple as that show menu unlock will be a flag that determines if the menu should be shown when the pointer lock is locked simple as that okay now we should change a bit our code and what we will change are this key down key up and unlock okay so first of all we will change uh the unlock to show the menu or not and here we will change the second parameter meter which now is simply the show menu okay that we get from menu JS to show the menu which is a module separated module here we will change the bit we will add a condition let's add first a function and this Arrow function this Arrow function we'll check this condition if show menu unlock okay then we show the menu so if this flag is true then we will show the menu simple as that so we simply call the show menu okay that you know we have it imported and yeah else the show menu unlock will be false so show menu unlock will be false that's it too many comments but yeah in this part we add this event listener to the unlock event so we check whether to display the menu when the pointer lock is released and after after that we rested the flag back to the false value okay now next thing we want to do is to create a function to toggle the pointer lock so let's create this function and let's call it toggle pointer lock so function toggle pointer log it will take as parameter the controls and inside the function we will check the condition to toggle it if log pointer so if it's true the variable loog pointer which initially is true then we want the controls to be locked that's why we have the parameter controls because we want to set the controls to lock or unlock okay so without getting confused if you see the code it's way easier so the condition if lock pointer which is the variable that we just created if lock pointer what we do we lock the controls so controls. loock else if the condition is not met that what we want to do we want to set the controls to unlock so controls. unlock okay so we have the controls as a parameter we will call it in the main JS etc etc etc but also in the else block we also want to set the show menu unlock to false right show menu unlock it will be false I hope this is clear the last thing that we want is to toggle this loog pointer here so loog pointer equal exclamation mark loog pointer which is basically set the buan value to to to its the contrary so set it if it's true make it false if it's false make it true this is the meaning of this exclamation Mark but yeah I know that you already know this I'm just reminding you the basic things okay so this toggles the lock pointer variable that we created at the top just tole okay and that's it for this part of code this function is called when we want to toggle the state of the pointer lock if the pointer lock is currently locked meaning that the lock pointer is true initially we lock and V Versa or vice versa in English we also toggle at the end the value of log pointer at the end so this function is keep it up to date with the actual state of the pointer lock and this is done so now that we have this function toggle pointer lock we can toggle now the pointer lock when we press a key that's what we wanted to do right we wanted that press a key and toggle the pointer lock in game mode or using the UI elements so being able to use the mass events okay since now we are not able to use the mouse events on click because the poter lock controls won't let us so with this function we will disable or enable them based on how we want it to be so we want the pointer locks to move but when we want to click something we want to stop and deactivate them and simple as that we will do it when we press a key so this is a custom way function to to make this to solve this problem that we had that some people requested in the comments okay so we have this function toal point a lock let's create a condition no not here but we will create the condition inside of this Onkey down event because there is where the event keys are registered you see event keys in key press that we have an object if you uh forgot we have this key pressed that if you want to check it quickly okay it uh has all this uh values false or initially and then we check them if they are pressed Etc so this is to control the event keys that we press the input by the user and here on this function on key down that is the event that checks if we press a key below this condition that we already have we will add our new condition so if we press the space bar we will choose space bar for this we can use any other key but I think space bar is uh yeah it's uh better it's practical so if we press the space bar we toggle the point l so if it is true it will be false if it is false it will be true we toggle it if EV that key the same equal oh equal for the space bar is just an empty space here we toggle we call the function and that's it toggle pointer lock and we pass as a parameter the controls here this is this space bar making again the summary of this function will be used to toggle the state of the pointer lock which means that if the pointer is currently locked it will be unlocked and if it's currently unlock it would be locked okay it's a playing with words this is a convenience feature for users to easily switch between the game mode the immersive mode and the UI interaction mode that we can use the mouse events we can also add other checks for other keys that we want to use for example we can set a key to start the audio we can set a key to stop the audio we can set a key to show the menu and many other things we can do all of that okay maybe we can use uh now the Escape key so if we press the Escape key we want what we want to do if we press the Escape key we want to set the controls to unlock okay press the escape and it will be unlock also we want to to show the menu so we will set the show menu on lock variable to True uh let's do it with code so it's easier to to understand so again the same thing if ev. key equal is Escape which is the code for the Escape key we want to do a set of things first of all we show the menu we press the the Escape key we want to show the menu if we are let's say uh with the pointer locks you know we press Escape show the menu stop the pointer locks or you know the exploring mode so first of all call call show menu then uh we want to set the variable to true the show menu unlock which is uh responsible to check the state for this so show menu unlock to True also we want as we said to set the controls to unlock you don't get to be confused with lock unlock because you know for the controls but I think now you are familiar with this so set the controls to unlock also as with the menu we want to change this variable that we had at the top so the variable that which is responsible to track the state so log pointer we set it to false in this case Okay so the lock pointer is false and that's it we also have this for the Escape key okay you see I press the Escape key I show the menu and set it the unlock controls okay so it works what else we can do we can add also the enter key to start the game to start the the exploring mode so if we press the enter key what we want to do let's say uh now we have the menu okay so what we want to do and the also the controls are unlocked so if we press the enter we want to hide the menu and also we want to set the controls to lock and set the variable for that it's easy it's this the same thing you can do it without my help so if ev. key equal to enter as we said we want to hide the menu first so called HDE menu okay that you see we imported hide menu and show menu from the menu Js which we have here okay you see we have two functions show menu and high menu which basically wheel Styles they show our height simple as that where are we okay we are here so if we press enter we hide the menu also we said we want the controls to lock so controls do lock okay and don't forget to set the variable to true so the variables is responsible to you know to check to be set because with that variable we keep track of the state of the pointer logs so log pointer set it to True okay and then that's it we also have Escape we have enter and uh we have the space key okay guys I was testing it so the toggle pointer lock when we hit the space bar doesn't work and let's check okay I see a few issues here that we should fix but first of all let me change this variable name and then we fix the issues okay so these isues are two issues the first no three issues actually the first are these two event listeners here the first are these two event listeners here we should pass the event and the controls also we should pass the controls here because yeah of course we are using the controls so we should pass here as the parameter controls this is a space should be correct so the only thing to fix are these two event listeners okay so let's fix it so here on this ony down let's pass the event cre ER function and on this ony down let's pass the two parameters event and controls okay the same thing for enia yeah okay it should be okay now here we have the controls here we have the controls I think it should work now let's try pointer locks are enabled let's press space okay it works ah okay okay it works the first time but the toggle doesn't work so this is correct but the tole doesn't work so the second time that I press the space doesn't work and probably is the problem here okay I saw it here you see controls. loock the parenthesis okay we should call it this lock method and yeah I think yeah unlock parenthesis yeah yeah I think that's the issue let's try press space it works okay press again it works yes now it works this is fixed okay now that we fixed the pointer locks controls toggle we want to add the functionality that we discussed previously so we are going to help the users interact with our 3D scene by enabling them to click on paintings which will then open up Associated web pages something that uh many of you wanted to to have the main components of these features are first The Click event handling then the ray casting that we didn't cover the painting object interaction and to break it down with the explanation step by step uh let's see the code that we are going to create for that first of all let's create a new module and let's call this module click handling and first thing first we want to import the three import three front three okay and before creating the function because we need the function click handling we need two variables okay so these variables are the mouse coordinates and the Ray Caster let Mouse we create a new Vector two for this so from the three new new 3. Vector 2 and for the r Caster let R Caster new three. raycaster okay now we created this module and now we will create a function with the same name a click handling that will accept some parameters so function click handling with the parameters renderer camera and paintings arguments actually so render camera paintings okay we don't have this defined anywhere in this file but you know by now that we will call this function here in the main JS and we'll pass you know the camera etc etc I will create this function and we'll explain it after writing it down uh what I wrote and why and step by step with the explanation of it okay but uh the first thing is we want to register an event listener for the click event so each time a click happens we want to register it in the screen so later we know if this click was in the painting or not so access the renderer then the D elements and we attach an event listener to to to this uh D element sorry so add event listener and it will be a click event then with an nrow function that we pass the event to to use it and here we will use the coordinates for the mouse for the X and the Y uh coordinates okay so here uh the mouse that we created the vector 2 mouse. x and we should normalize this but I will explain after writing it so mouse. x uh we assign it to the event. clientx okay divided uh you have heard of this when window. inner width and window. inner height do you remember inner width and we normalize it for those that uh don't know what I'm talking about I will explain minus one and the same thing for the Y Y and here inner height okay here we registered an event listener on the click event okay I sorry I have just small back here this is plus we registered an event listener on the click event and each time a click happens we normalize the mouse uh position to range of minus1 to plus one for both X and Y this is because 3js uses this range to represent the screen space we then call the onclick function passing the camera and the paintings as arguments so onclick pass the camera paintings okay and this is done don't get confused by this formula here is just to normalize the coordinates for the X and the Y because 3js uses this to represent the screen space and that's it nothing uh you know to be afraid of yeah I have a small typo here the next step is to implement the r casting and we didn't cover R casting we wanted to cover it when we uh made the Collision but I found an easier solution so we didn't use R casting on that part uh since we want want to handle the click event using uh this Ray casting technique the Ray Caster to to explain it uh simply is an object that emits a aray from a specific point in a specific Direction This Ray can be used to check whether any objects intersects with it or not okay in our case we are using it to see the user's Mouse uh when it clicks intersects with any of the paintings that we have in the scene here we create the function uh on click we pass Cameron paintings then we access this Ray Caster and we have a a method here set from camera I will explain and we pass the mouse and the camera then we create a variable for the intersects con intersects and assign it to R Caster do intersect objects method intersect objects okay objects not object and here we pass uh what the paintings what we want to intersect paintings in this onclick function that we just created we use the recaster set from camera method which takes the normalized mouse coordinates for x and for y as arguments and also the camera we then use the requesters intersect objects to get an array of intersections between the array and the paintings each element in this array represents an intersection and it contains information about where the intersection occurred what object uh was intersected etc etc so we have this the next uh step would be to handle the case when the intersection does really occur so if this intersect array that we mentioned is not empty it means that the user has clicked and uh it was a painting there where we clicked and in that case when it happens we grab the first intersection uh which will be the closest painting that the user uh clicked on and we will perform our desired action in this case we will just open a new uh web web page we will be redirected to to our shop our landing page Etc so to implement that add the condition if as we said if this intersect array is not uh empty and for that in javascri scrip we check with intersect if intersect is greater than zero here we create uh first the a variable to to access the painting so the first one painting sorry const painting the first uh that we get in the array so intersects uh uh index zero that object here perform the desired actions okay we can conso log we can conso log here the the clicked painting So clicked painting and here we pass the title of it so we know what we what we click and that is we get it from painting data painting title where is it title so info title okay but this is the user data object which is here in painting. JS this user data so so here to access it painting. user data do info. tile okay since we are there we want simply to to open an external page so for that we use window. open here and we pass the link that we want to open we can simply add here the URL but it will be added here in the user data so a new property here uh URL and also add it here yeah I already edit here the URL so for that I can simply or back W okay I have it oh I have it oh yeah I have it I can simply add the link here and we also have the URL here so for that uh we can access this uh the same with painting user data info link painting user data info link open it in a new page so blank and that's it it should work the last thing here is to call this function click handling in the main JS so we can also get we can also get this arguments render camera paintings so here import it click handling okay and let's say here call it click handling and pass render camera we said and paintings right render camera paintings render camera paintings yes let's try now if it works or not we disable the point of locks first now we click it doesn't work let's see the console lock on click is not function on click why is see lower case it should be uppercase right I click yeah it was a typo disa poter locks controls click but now nothing happens oh if intersects greater than zero if intersects that length it's an array but I don't think this is the issue yeah exactly this is not the issue oh okay so this is for 3js to normalize the screen space we set from minus one to + one so this is minus here this is minus here I think think this is causing the issue yes it works that was the issue if we click here nothing happens if we click on the painting it intersects and it works so it organizes the paintings okay and this is done you see also it's console locked clicked painting vangog 2 click painting vangog 3 or vangog Guan so it works and that's it for this part of the tutorial I think we have implemented this feature that was requested we also added the audio guide maybe we go and implement the VR support for our 3D art gallery what you think it would be nice to make a tutorial on it but I will think and we can maybe add another tutorial about web Pixar tell me your thoughts and if you would like to add this webar support for our art gallery or not or if you have any other suggestion thank you for following me and see youunlock the world of 3D web experiences with this beginner-friendly 3js tutorial you will learn how to create an interactive 3D art gallery to Showcase your portfolio in a dynamic engaging way this course will cover all you need to know about 3js fundamentals such as scene camera renderer geometry materials and more amelon created this course and he will provide you with Hands-On lessons on animation meshing user interaction and utilizing a gooey bugger for real-time configuration all designed to empower you to bring your Creative Visions to life on the web hello everyone in the next 8 hours we are diving into the world of 3js to craft an interactive 3D art gallery this is what we are going to build so usually I go in Windows plus air write CMD open on the terminal here in the terminal CD desktop so I will create my project in the desktop then MK deer this creates a folder in the desktop and the name of the project so Art Gallery simply okay we created the folder let's get into this folder CD Art Gallery okay and now let's open it in our vs code we usually use vs code is the best editor out there so code and Dot okay we are in the vs code we have this folder now we need to create some files that we need usually we need uh HTML file uh of course a CSS file for the styles and also the functionality that is the JS file with JavaScript okay uh if you don't know we are working with this project we will work with this with 3js okay 3js is a cross browser JavaScript library and application programming interface used to create and display animated 3D computer Graphics in a way web browser using webgl okay uh the source code is on GitHub it's open source so it's a very nice Library I really like it I am a fan of 3D usually I I used to work with unity Unity 3D in my opinion Unity is the best ever tool out there for me but I really like also 3js if you want to create Games Etc Unity is is like the best tool for me also unreal but I am a Unity Fanboy but if you want to work in a browser with 3D models or you know 3D programming for web applications 3js is the best choice there is also babylonjs it's also great and it's maintained from Microsoft but yeah I think 3js it's very uh easy I mean very easy it's like let's say easy compared to you know other Frameworks that has a very steep learning Cur but 3js if you know JavaScript it's very easy to get into if you are a JavaScript developer okay so no more talking let's create let's create first uh an HTML file okay we need an HTML file so index.html okay let's create the template so you just simply write the exclam uh I don't know in English but I think it's called like that okay so we have the template right let's create uh immediately the other files so we have the structure you know the structure of the project and so slowly we can build the project okay so the index HTML create one let's create a folder so it's better to keep the files on folders with a specific name so JS for example we have here the files uh JavaScript files that there might be many files or only one file one main file maybe we can create everything inside one file but we might need other files so let's create a folder JS let's create the CSS folder also oh it's created inside oh sorry come on delete permanently okay CSS folder okay let's also create the file so style. CSS okay and also a main JS file main.js all right so we have have here uh what is important and I think we can do it since the beginning we should import the module of 3js so we need a module uh by 3js you can go to Google and uh simply search 3js GitHub module or something like that and here you will see this is the Mr dup it's the maintainer and creator of 3js and you can download the file here if you are familiar with GitHub you already know if you're not familiar with GitHub uh here in the green button click the green button uh download the zip file and inside what we really need we don't need everything here actually so now it's uh it's not very light it's like there are many files here many files but what we need is inside inside the build okay inside the build folder so after you download it I already have it that's why I'm I don't have a problem I already have it if you don't want to go through this I will I will post this project the whole project on my GitHub so you can simply go and copy the file in my GitHub if you want to know this because maybe you will need it with other projects that you will create yourself so it's good to know we you will do this every every time you will need this inside the build folder you will need this three.js file or 3. MJS it's a mini ified version so the minified version or the 3js this is for modules it's like you if you are familiar with es6 Etc it's like built uh but for now you you just need this one 3js or the minified version I will go with the this file 3js okay so here code download I have it here so I go and will copy it so three file let me go to this folder so reveal in file explorer I will put it here all right I am not using the minified version but the minified is lighter anyway this is just a propose of a tutorial let's go back so we have the 3js here okay let's create if you want to take a look inside maybe it's you know it has classes Etc about every everything you see is pretty pretty big it's there are there are a lot of classes methods functions and every everything about 3js that we will need to to to create and do 3D programming okay but let's leave this for the advanced guys so let's go to our HTML files let's change the title First Art Gallery okay maybe let's add the CSS file so let's edit now and uh we will need it later so uh here about add link okay Styles sheet so HRA it will be in this folder CSS so CSS style CSS okay great so let's build the file maybe first let's open this in our browser so go live here go live go live or click the right and then open with live server or the shortcut alt plus L all alt plus o okay so here is our project it's here on this uh address in our local we don't see anything because we don't have anything so let's create some files here so we can see what we will need we will need you know the we will need the background the main background that we'll have I don't know we have the scene of our project then another it will be a div so then another div inside will be a main container maybe uh then an H1 we will make like uh we will make like a menu when we first click uh our project it will open up a menu with some information you know the title Art Gallery Etc and maybe some instructions or you know it's up to you actually it's up to you but let's make a very easy one a very simple one so let's create a main div and let's give it a class name of background or background menu so if you want to be if you want to have some shortcuts to be a good developer if you don't know maybe many of you already know these things you know so don't bear with me maybe some others are beginners and they would like to know these shortcuts to be fast and you know Pro tips so if you want to create a div not going to div and then give it a class you know so div then go and class and then add the class name menu Etc there are some Pro tips so you can be quicker and faster so dot and the name of the class the name of the class will be for example background menu so do background menu enter this is the EMT abbreviation and you see it's quick and it's fast it's a nice shortcut or it's my oh my God it's myal okay so again you will make you will create another div with another class the same thing so dot and put the name of the class it will create a div with a class name ready okay so go with these things and you are quicker or if you don't want the class but you want maybe an ID so this uh sign of the ID and then put the the name of the ID that you want and enter it will create the div with ID menu okay what we need and then inside this menu we will inside we we will add the title uh maybe we will add an image okay we want a nice image they want to show this Gallery before and maybe click button like uh explore explore the gallery or enter the gallery uh Etc so we have menu div let's add the yeah let's add an an image let's create a div with uh image container so ID and uh image container okay and inside let's set an image okay this will be the source I will let the image now and you know just menu pick doesn't matter okay uh let's add the the picture yeah let's set the picture oh this is my pictures don't where do I have those pictures I have some okay I want to add this the stay night that's why maybe create a folder for this yeah let's create a folder for this image let's set it inside okay let's set the source so image ster night great let's change the AL here night good okay we see something here in our browser so what else what else we need uh yeah we need the title you know the menu we need the title so a title and description Maybe yeah title and the description okay so title image uh description what else we may need we may need like uh or maybe let's keep it simple yeah let's keep it simple for now let's set maybe an image a title and uh a description okay so this is for the title and uh yeah let's keep it for now ID this is will be the content the content and yeah and each one that will be hard color okay and uh it will also have the description and uh inside let's create a P A P tag with a description this is an interactive uh 3D gallery okay uh description maybe some other description if you want made with love and 3js and 3js okay what else yeah we see something here what else what else uh yeah maybe we will need like some instructions how to move what we will do etc etc right okay so instructions maybe bet always instructions here B tag again move left or right it doesn't matter Arrow so arrows and look around look around with mouse yeah uh let's set maybe a bom to start to play it's like just play Enter G okay let's give an ID to this one play button okay okay it is something also also we need the scripts okay we also need the scripts we will add here the 3js script so and you have you should keep in mind something here a the script and here in the script SRC we will put our 3js okay you should keep in mind always always uh add the 3js script before everything else okay so above all at the top you add this script of 3js and Below you add the MJS file etc etc okay so like this it will be uh JS you don't need the dot and you know so simply JS no main JS it's threejs so JS 3js okay this is it another script okay you see how I cop it you can put you can press shift alt and the down arrow and you copy like this okay so shift alt and the arrow down let's change this one this is for the main Js Js M Jaz okay uh so we have pretty much much everything here for the HTML maybe we should add the Styles and then we can work for the real project with JavaScript and create everything set up 3js set up the canvas the camera render objects and you will see yourself everything else okay so styles let's set some Styles maybe if you don't want to follow along about Styles it this really doesn't interest you the HTML ex you can look uh the final result or just grab and copy and paste from my GitHub so just don't don't worry or just forward I will add some Styles here there is nothing to really explain so we'll add this style so why is Skip okay there are also some shortcuts shortcuts for for the CSS if you don't know those are our beginners so for example I want the width 100% so not going width and then 100 I can simply write uh W and 100 enter and very very quick the same age 100 quickly for the font size F uh s and the 12 size you have the font style or font or sorry it's font style I need the font size okay whatever but yeah there are this shortcuts also called color let's give it like I have some this is the result of the CSS style you can copy this in my GitHub so let's leave the CSS and uh let's open our jsjs file and here it starts the 3js project so we want to click this enter the gallery after clicking it U the menu will hidden and we will see this 3D object where we can interact and move around we will put a big box there you know we will put M the floor we will put the walls and then create create you know the paintings that will be some some planes and we can put there attach uh a texter and let's see together but first of all we need some Main and important things when we create a 3js project that pretty much you will do a every single time these are the main Concepts and the main things you would need in a 3js project so everything you will work here in this file you will work by using this file here 3js that inside it has everything and if you want to check it yourself you can console log this big object because this is an object it's a very big object if you want you can console log it and see yourself and inside uh the three so uppercase three oh sorry sorry okay three let's check let's conso log f r three is now defined okay let's see let's see here I think it's a problem here CJs 3js s CJs M JS okay guys I stopped the video for a moment I went and I drank some water I changed my t-shirt I have my piggy blinders hat and got myself a cup of coffee uh no I don't drink coffee I take tea my dear like the song by Sting actually it's Jin sank not a coffee uh for my brain my small brain okay so this uh we had this error and it's it's just a stupid error actually it's usually when you see this error like uh you cannot get the 3js and because execute because it's my typ ET ET this just most probably we just uh mistyped here the source uh what's happened here I don't on tell script okay so it's just here the problem maybe we uh have a wrong path or mistype or maybe you are uh directing a path that it's not a JS script but it's like a CSS or Json or etc for example I just make this stupid errors sometimes so I didn't see that uh 3js is inside the JS folder and I thought is inside but not it's not inside it's outside as you can see so let's put it inside the JS folder because you see the path JS 3js okay it's inside it should uh work now and the should okay it's gone is gone U I was showing you before these three object let's give it a name okay let's take a look here console log you see three object here and this is very very big object it has like everything inside you know everything that we might need to work you see if I go and click on any of these you there are a lot of things uh inside of that okay so the three Library this file that we imported uh contains most most of the classes and properties that usually we might need on a classic project with 3js okay but but sometimes not every class that we might need is inside of this but we will talk about it maybe later when we will go through that problem okay because sometimes we need some other classes that are not inside this three and we should import it from another source okay but for now let's leave it so comment this one so guys we have the HTML file okay here we have like the Styles you can copy the CSS Styles if uh just don't worry about that just copy and paste the Styles uh we are not here to learn CSS but we are here to to do something with 3js and 3D okay so we have HTML we have the Styles now we want to add the interactivity the functionality with JavaScript or more exactly with 3js library and uh where to start where to start we will start by creating the canvas and then we will add a camera like in a movie scene okay because the canvas there is the scene we will need a camera like in a movie scene and then we will need a renderer so we will create the renderer to render the scene and the camera uh we may have have lights uh shadows and everything also in our scene we want to add the 3D models okay so our Gallery uh cubes uh and every kind of shapes that 3js has the possibility to to work with with with those geometries okay so first of all the first thing let's create the scene the most important thing and the first thing we should do create the scene okay so for that we just normally uh we just create a variable with the with the S okay and just save it there there are different methods to work here we can just work by creating the variables the functions uh Etc or we can create a an object and put everything inside this object okay it's like replicating the name space in C okay if someone of you uh is using C especially with game development you create like a namespace uh JavaScript doesn't have an mpace it's something that it's called G object okay where you put all your variables functions that then are methods Etc okay but let's keep it simple because I think we can do everything inside one single file in inside this main JS okay so we are not going through that you know pattern of object oriented Etc with objects just we can simply create so let scene or const SC because the scene usually you will not change it so it's a constant so const scene equal and here the keyword new to create a new scene this is you have to be familiar with objectoriented programming because you have classes and then you instantiate a new object with the properties of the the class so in this case we are just keep it simple for this kind of explanations new think about it just a new a new thing that we are creating okay with some properties that it has uh uh with itself in this case we are creating a new scene new let's call three okay and then with that oh sorry it's just my sorry new three okay and then with that operator oh my God why is this calling three and then SC with that operator we access uh the properties inside this this this class the the main class of three it may have other classes it may have you know uh functions methods properties and everything else okay so three. sin and parenthesis and that's it this is our scene let's put some comments I will let some comments during the the tutorial so when you get the code uh on GitHub you also have it commented so if you forget or you know it's just for the beginners is easier so create the scene this one what else as we said we need the camera so let's create a new camera like in a movie set you know we have the scene imagine imagine this scene to to to see this scene we need a camera to to to look and because when we render it will be through uh you know the eye of our camera okay so the same thing as we did with the the the Sim to to create a new a new camera we simply go by just const camera because it will be again a constant so const camera and with the specific class from three library that it's called perspective camera and I will explain it now okay so const camera equal it so again new and again three from the three Library we are accessing this three here this time we are accessing perspective camera okay and it accepts some parameters that I will explain now but con camera new three perspective camera the camera uh actually is not uh visible we cannot see this camera it's more like a a point of view okay so when we will do the render later of our Scene It will be from this point of view so from the camera's point of view we will render the scene of course like in a movie scene there are different types of camera and maybe we will talk about it later if we will need it not for now for now we will simply use uh this one the perspective camera it's like the perspective it's like making close objects look more prominent than the than the far objects the objects that are far okay so that's it to create you use this one one uh using this class perspective camera there are two main parameters that we need to provide inside there is the field of view and there is the aspect ratio I think you may know what the aspect ratio is it's like width divide by height okay width divide height you sa the the aspect ratio the field of view is uh how large our vision angle is so for instance if we use a very large angle we will be able to see in every direction at once but it will be with much Distortion okay because there result will be drawn in small rectangle but okay leave it for now if we use a small angle things will look zoomed in so the field of view is uh expressed in degrees and uh it corresponds to to the vertical Vision angle so here for instance we will give this parameters so 75 okay and this is the field of view it's like you know what I found that it's it's it's it's the correct let's say but you can play with this depending on the project so the the field of view and we also said a few moments ago we have the aspect ratio so the aspect ratio is width divide height in this case uh what we are dividing here the width of what the the width of the the the canas that we have the same so in this case we want it we don't want to to to put sizes okay we we will get the width of the window so the width of the whole window divide by the width the height of the whole window so we keep that ratio but using the window object that is the uh the window object of of the browser okay so window Dot inner width if you click the dot it you will show you know the properties divide by window do inner height okay and that's it a comment here so you have it clear uh aspect ratio okay then you as a third parameter and other parameters you can also add if you want depending on the project but this is for example 0.1 it's for the near clipping plane and also the far that I can put here 1,000 okay far and near and that's it for the camera that's it for the camera we don't see anything because we don't have anything in our scene we added the cam because the camera is not visible but anyway uh we created the camera but we always need when we create an object or when we create something in our canvas we need to add this to our scene so for that we have scene. ADD okay and as a parameter we add the camera this okay let's put some comments here s camera so we divided some kind categories if you want also to search and you easier okay we have the camera uh there is something that uh we you should not forget you should not forget for example if we have something in our scene we we cannot see it because we the camera when you create the camera by default the camera is in you know it's it's in the zero axis so we cannot see it it's like the camera is it's it's near the the the renderer so to to to make it possible to to look at the things we need to pull it back a little okay so the position of the camera in the Z axis will we will pull it back to to be able to to to see it's not a problem now because we don't have anything but it will be an issue let later so camera. position so we get the position property and then Z in the Z axis and a number five for example okay and this move the camera back five units good and this is done what's the next step the next step is the renderer we need a renderer also the canvas there are usually two ways someone will create a canvas here create a canas okay and then uh this canvas then access uh the canvas with a property like document that gets element by ID or by class you give you give a class or ID to to the canvas here in the HTML and access that and save it in a variable or you can simply create the renderer as we will do now without uh creating the canvas there and access it with document get element by ID okay so let's go for it and let's explain some basic things about the the renderer we will ask the renderer to render our scene from the camera point of view as we mentioned before and the result will be drawn into the conas okay so we mentioned that we can create the canvas by ourselves or let the renderer generated and then add it to our page so to our document uh body HTML to create the renderer we use the web GL renderer class as we did before with perspective camera class uh this time we will use the webgl render class with one parameter and that one parameter is an object you will see now render letter const render oh no always new three and we mentioned we will use the webg renderer class okay so to create the renderer we use this class webgl renderer okay and it accepts one parameter that it's an object okay and that's it let's just just just this one uh if we created the canvas here as we said before we will pass the canvas inside the renderer okay or let the renderer create that commer okay in this case in this case I didn't create a canvas in our HTML so I'm just leaving like that with the empty object inside this accept some other properties for example like ATI Alias okay I will explain uh what it is and this is for antialias means for smooth aging for the geometrist it will give like Smooth edges later when we we will let some geometries okay so we have the scene we have the camera and we have the renderer but we are not finished with the renderer uh we just created a new instance but we will set the size of the renderer okay so to set the size render do set size and again for the aspect ratio we will use window. inner width and uh window inner height so we will give this two parameters as the the size to set the size it sets the size of the render in this case the size will be the width of the window and the height of the window okay I hope it's clear window. uh inner width and window that inner height okay perfect we set the size of the render you can also add a B background color for the render for the canvas you can do it now or you can do it later doesn't matter but yeah since we are here we can give like a white simple and um the property to to to change the the color is set clear color it's not very intuitive but anyway and there are some ways to to change this to give a color you can give it like with quotes like blue red Etc or hexad decimal and you know you know those things so let's give it zero X and f f f f f is just for the white one and this is the background color and this is done the last thing you should not forget as we mentioned before we will add this renderer to our HTML for that doent body dot a pen child okay and inside renderer uh render yes render dot Dom element D element okay and that's it let's add a comment here so add the render to our HTML and this is done what else we can do we are still not seeing anything because we don't have geometries we don't have anything in our scene so our movie scene has no Act has no nothing it's like empty we only have the camera and we are looking to an empty SC we can also add the lights let there be light okay we can add like spotlights ambient lights all these lights have some properties like uh one has the property it lights the scene uh as a sun another one has some spotlights or Point lights we have different lights uh the lights we can create a whole uh new tutorial only about lights and shadows it's very interesting actually but for this tutorial we need just one or two simple lights two to to light the same lights let there be light one light that we mentioned it is the the ambient light the ambient light is like a soft light but that lights everything all the objects in the same but equally okay so let ambient light equal again I think now you are used to it new new keyword again three colum three ambient light uh why it's not suggesting me this I think it should suggest me the keyword normally but anyway we give a a color to the light it's like zero in this case just 0 1 0 one Z 1 Z okay also 1.0 this is for the color the first parameter for intensity okay again you also have some other parameters like distance and Decay but we are not using it if you just want to distance and okay but yeah okay so we have our ambient light also we can as we did with the camera we can give this light a position where we want to to to to put this this this where we want to put to put this ambient light in this case uh we can put it in the position of the camera where is the camera we want that light the camera moves it update lights with the position of the camera okay so ambient light our variable do position I think you guessed it position uh equal in this case camera. position okay and that's it again some comments light follows camera on Instagram okay so lights follows camera and uh I think many of you didn't forget that when we create something in our scene we should not forget to add this things to our scene with the with the add property so same. add inside ambient light okay and the light is created we can add not only the ambient light uh we also have some we have different lights but we can add at least another one the directional light and the directional light is a light source that act acts like the sun like you know in the in the real life it TS like the sun that it illuminates all objects in the scene equally you know from specific Direction okay so the directional light it it's it's like the sun and it it shines through and lights in a specific direction that we we are using it okay so let uh let's call it sun sunlight again new you are getting used to it okay so the more you practice the more you just get also in in in intuitive way okay even if you have not clear the the objectoriented programming pattern so you just you just get it I'm creating something new here and you know it's the new keyword so new again three accessing the three library and uh here directional light again we give it some color and intensity one two 3 four five and intensity 1.0 color intensity and we are done with the lights but of course you didn't forget again that we will always add this objects this things in our scene okay so again sin. uh sunlight now it's done we can also give some position since we said that this is a directional light we can give some position to it in this case since it's a a sum we will give a position in the Y AIS okay so it's like like this up and down like the sun it's like we give it a direction in this axis the y axis uh we will do it before adding it so sunlight. position you you see that it's very intuitive it's like not saying easy but you you you you can get through it if you know JavaScript it's that's why I like 3js it's intuitive it's it's it's a nice Library so sunlight do positiony in the y axis let's uh give it 15 so we have seen with camera we have the renderer added to our HTML and we have the lights in the end uh we want we want to to to to add the scene and the camera to to the render we need a render because the render is like the screenshot okay for the screenshot we need the camera and the SC that we are taking that screenshot okay so camera and scene that we are taking that screenshot like a screenshot so we need the render and to get the render we access the renderer variable that we created here above this one so render and for this renderer do render yeah it's a wordplay uh with the parameters same and camera because as we said to take the render to take that screenshot we need the camera and the scene that we are we are screenshotting okay uh something things to remember maybe if you don't see nothing after you create objects in the scene you we you should take in mind that uh you should specify the position of the objects or the position of our camera so we should not forget the camera it should be like pulled back a little so we can see things because if not out it's like I I I I go near the the the the camera of my laptop so I cannot see anything or reading the book it's like going like this so of course I canot see anything so I just need to put my eyes my field of view a little bit back so pulling back later when we will create the the objects you should also keep in mind to see the position of the objects if you are not seen anything render in the scene okay so we need to move things uh many times with 3js and that's it for now that's it for the main things the the main concepts of of of the scene of the canvas of 3js now we are going to do add some objects and we want to see something because we still don't see something this is just HTML it doesn't have nothing to do with the canas it has nothing to do with the three 3D World and 3js okay so we we created this lines of code oh that's why uh oh look look look I didn't see this maybe this was the reason I Your Parts was like the it's the old syntax of node but uh I don't need to import it if we use the server if we use webpac and express sometimes you need to import the three like import three from three it's like in react if you are used like you import a module that's why I was talking about modules uh before so if you use use a server Etc we will use it maybe in another project usually you import this three Library here the whole thing it's like import Asterix S3 from three like import everything from three but not in this case we just have it here in the scripts okay we are pointing to this path and we are just simply using it okay so we want to add some objects right we want to see something so like all our effort means something because now we don't need we we are not seeing anything but let me drink a little bit of some Gin sck uh also my cup are made of you know art this is like paintings I have a collection with different paintings this one is OS M okay I have like many of this with different paintings and pieces of art anyways so let's go for this object for the objects it's usually like we other 3D programming tools usually you create a cube you know the basic one the basic geometry we love the cubes we always start with a cube if we use um any other 3D software you know that you always start with a cube or you always start by deleting the cube the poor default Cube for example in blender those who use blender or work with blender they know that they open the program and the first thing they delete the the poor default Cube okay so we will create a cube just to see because later this Cube will be a box for our Gallery but since we are here for the beginners we need to explain a bit things step by step so bear with me please and also if you think that my English sucks at times I know it's not my native language and you know I can speak well at times you know but when you are live and explaining something technical it's you know you may have some problems so please uh understand this I know it can be frustrating maybe the accent or you know when someone doesn't speak very well their native language but okay anyway let's create this this this geometry uh yeah in the end here let geometry you see guys that now I see this I was wondering why I was not seeing any suggestion it was weird for me I added that line of code I don't know why I just it was the shortcuts I should delete some shortcuts actually sometimes they are a good thing sometimes they confuse you sometimes you don't even know that you created a line but you created it by by your shortcut or like GitHub copilot it it is great many times but sometimes if you don't know what you're are doing or you know just clicking you can add some line of code and get confused so first of all to create a 3D object what we do we create a geometry and we create a material then we create a mesh and we add this geometry and material inside this mesh seems confusing don't worry it's not it's uh pretty basic concept that the moment that you write it yourself you will just get it if not the first time just the second time it's I I will assure you that you will get it and it will become a second nature to you so let geometry again you know it now without my help new three and then uh do what I added something new you see that I added this I don't need this uh geometry new three for the geometry we need a class that is called box geometry box geometry and it accept some parameters uh for the three axis x y z it's like you give the size of it one one one simple one a small box box geometry is the shape of the object so we have the shape we need the class mesh basic material and uh the material is nothing else than the color so inside to add the color we we put the curly brackets the an object and inside this object we add properties in this case the property is color uh this is the color of of of of of it and in the end we create a mesh again new uh new three uh mesh as the name suggests and inside this mesh we put two parameters geometry and material geometry and material this creates the object okay great so we have it uh I think you know now what we should do right you know I'm sure you know we will add this Mash to a scene scene. add Mash this MH has the material and the geometry so this match is basically the object uh we can try and test it but I want to to to maybe explain maybe explain some basic concepts here so to to to reflect again what we did a vis visible object um like a cube to create it we need to create uh this type of object named mesh okay and mesh what is mesh it's uh simply a combination of the geometry okay and the the material the geometry is the shape I've added the comment here and the material is how it looks the color in this case but later we will add you know texter uh there are some other things but it it's how it looks the color in this in this case so you start with this geometry that is the Box geometry class okay that has three parameters that corresponds to the size the size of the Box the geometry okay uh for the material for the material we use the class mesh basic material uh it has one parameter and this parameter is an object okay containing all the options so the class mesh basic material with one uh parameter that is an object with all the options inside we have the property color so then I think you might know that to specify a color in 3js or in in JavaScript uh we can add hexad decimal uh number uh we can we can add the simple string like uh you know we can add it like this or uh as a string uh to to to to Ed it as a string we sorry we had the sign how is it called this sign I totally forgot English you know the ID sign anyway okay so there are these different ways to to or you can simply call it red like this okay for further information you you you get it in the internet so the final uh the final thing is the mesh so to create the final mesh we use the mesh class this one that we send inside as a parameters the geometry and the material okay and that's it in the end you add it to the scene let's see if we have any errors because yeah Art Gallery yeah I sorry it's the the the audio three has already been yeah of course of course that main JS has already been declared okay again this one that I sorry guys for this let's see okay 3. sin is not a Constructor having errors is normal you know it right see that's in yes looks okay okay so this sors is just a small back insignificant because it's just a typo it's not scene but seen uppercase okay so let's check it's normal I will not cut and edit these videos I will leave this mistakes and errors so yeah you maybe you you can learn from from this errors so I will not edit you know and cut the the parts of the video where I make mistakes oh okay we have another error uh what's this one cannot read properties of undefined render why let's check and Define render render render render render oh why I have this three here it is not needed so it's just renderer do render without three I don't know I have no idea why I wrote that but okay let's check okay finally no more errors uh it's good to know that we don't have errors but uh we want to see the object that we created right we created uh where is it we created here where is it okay we created the cube so we want to see that Cube so geometry and material added to a mesh as parameters to create this Cube so maybe here instead of mesh instead of mesh uh let's call it Q it's yeah it's let's call it Cube so this is the cube created with MH that accepts geometry and material but we don't see it we have just this uh HTML element we have no Cube but uh actually the cube should be behind this element because the canvas is behind this so we are covering it I think so let's hide it let's hide the whole element inside the body and we should see it now oops we don't see it uh let's check if any errors no errors no bugs but we don't see the cube why okay guys I am not uh cutting and editing this Parts uh where I have some some bugs so yeah let's find it together where is this problem I think it's it looks okay in correct so we have the geometry new three box geometry we give the size of the geometry okay this is correct we have the material we create a new mesh basic material inside an object with this property of color and this is also correct I don't see anything any typo but if we had a typo we would have an error here we don't have any error so this is like those cases that you have a problem but you don't have you know an error so it's like a hidden bug okay and yeah we shoot the bug and find it if we can I don't know guys if you see something wrong here I don't see it Cube It's a new mesh with geometry and material okay this is also correct and we add the cube to our scene we render it with scene and Camera this is correct guys this is correct let's see maybe the camera we pulled it back the camera uh the problem that we talk we talked about so let's check the position of the caram yeah yes here we move the camera back of five units so we should be able to see see it it's not this where is the problem render is okay the camera the camera the position of the cube did we move the cube the position no we didn't perspective field of view oh oh oh I got it I got it I got it okay that's why okay that's why you see here the perspective camera I told you that we need the two main parameters the field of view and the aspect ratio so we have the field of view we have the the aspect ratio and then I I I said that we can add the two other parameters for near and far okay but this one here I have no idea what it's doing there this zero so it's like it's like the third parameter it's like this is the near okay and this is the far so it's zero so yeah I I think this should be this is the buck okay so we have one for uh 0.1 for the near and 1,000 for for far so it was like a third parameter I I don't know let's check let's check should be okay perspective field and com pull it back yes let's check okay great we see it our small cube our little cute cute Cube okay it was like somehow hidden we okay so we have this object guys and we created it uh maybe we can make a small animation okay of it we can make a small animation and this is the yeah this is the the time to talk about the animations what are the animations yeah you know what are the animations but what are the animations in 3js and the case is that that we we do here so let's do something and let's explain it uh a bit okay so we are here for the animation actually we need to create the render this one here uh we need to create a function like a loop and this Loop will make possible to to to show this animation so for each frame I will explain it now in detail so we need the we need a function first so let's call it uh let render Loop or something like that okay so I will explain it like in detail because this is a cool thing it's something you know it's uh nice to to to to learn and to and to to to play with it maybe so a function render Loop function and then okay uh first let's put this inside to move this hold line you can uh press alt and the arrow the error up and down okay alt and error up and down just another shortcut uh okay we don't have a parenthesis here okay yeah I'm making many mistakes today uh so about the animations what we want I want to to to to rotate this this this Cube and to rotate this Cube uh I need to change the position of the cube right so this one here and to change the position we will change uh sorry not the position in this case because we will change the rotation sorry so the position we we moved uh before uh the camera Etc but in this case we need to to change the rotation so Cube Dot rotation okay uh rotation. X in the xaxis equal cube. rotation do X plus uh let's give it like a very uh very slow motion to rotate so it should be okay like 0.01 okay let's do the same for the Y AIS okay I cop it here and let's change only the y y here and Y here okay so this is what we need to rotate the cube in the in the X and in the Y AIS but if we check now we will see that nothing happened uh let's see this error no error but okay we need to call this yeah we need to call this render Loop let's call it only render okay so rotation and render as the see in the camera okay now we are back but again we don't see the the rotation we don't see any change as you can see it's it's it's the same why because we need something else we need something else and I want to explain uh something uh at this point so about the the animations the the animations when we use 3js uh they work like you have uh the idea of the stop motion yeah that's it uh we move the object and then we do a render and then again we move the object something more and we do another render Etc and so on the more we move the objects in the scene between these renders the faster they will appear to move okay yeah it's seems a little bit complicated like explaining it but the idea is the screen we are looking uh runs at a specific frequency okay so we call that uh a frame rate and you have heard about the frame rate I'm sure the frame rate mostly on on the screen but uh it depends on the screen and the computer itself has some limitations okay most screens run at 60 frames per second okay some screens can run much faster you know it depends on the computer some computers are faster some are slower and so on and when the computer has uh these difficulties processing uh things it will run of course more slowly uh in our case uh for the animations we want to execute uh a function this function here the render function that will move these objects and do the render on each frame but regardless of the frame rate so regardless of the frame rate that one computer has it you know regardless of it we want this function to to to do the render on each frame in JavaScript not only 3js but in JavaScript uh the way of doing this is by using uh request animation frame we can search for it together request animation frame okay is from the window object okay this one from MDM window. request animation frame uh the window request animation frame method tells the browser that you wish to perform an animation and request that the browser calls a specified function that we talked about to update an animation before the next repaint the method takes a call back as an argument to be invoked before the repaint okay let's leave for now the documents you have it here you can read it uh more in depth but let's do it because things uh you can understand things only by doing it and by a practical example so let's set this request animation frame that uh we we we saw so request animation frame and we pass here as an argument the function itself the render okay let's let's see now okay you see you see we now have this animation a small one we can change the speed here of course but yes we did it we have this animation thanks to this request animation frame okay and uh this is um it's simple uh here we can refactor a little bit our code instead of this we can you know just a shortcut another shortcut we we like shortcuts you just delete this and add a plus like this is here plus and delete this one it's the same thing okay it's the same thing so it's like saying uh plus equal it's like saying Cube rotation. x equal Cube rotation. X plus uh the number so it's the same thing let's check okay yeah nothing changed it's cleaner so we also made the animation what else we can do now uh I think we can add the movement so we can move this this little guy here our Cube we can move it you know at the controls left right up and down okay it would be cool to to to learn also this let's find a way a place here and uh let's set this one uh control controls okay and here we we also need to to explain some some other things but of course for beginners for those of you you can just keep this Parts those who are Advanced and just are interested in in seeing the final result you know the advanced things about to create the the the art gallery but for the beginners uh stay with me so to add the the controls uh what we what we will do we need to press a key of course uh the errors on our keyboard when we press the left uh Arrow we want to move to to the left left we press the right arrow we want to move to the right or not only the errors but yeah uh in most cases when we play a game we move with a D and W it's the same thing uh for this uh we need an event listener those of you that know JavaScript of course they know what an event listener is uh for those that don't know you maybe should check Google event listeners and learn about it a little bit but we will make things very simple here and even if you don't know you will understand it the moment that I will write it down okay so yeah I think you will understand it just by looking at the code and this is the the thing that we need to to to to always do write a code that it's very readable so let's add this event listener that when we press the keys uh it will listen to to this keys and then we'll make you know an action uh comment controls so in this case uh event listener when the when we press the keys we press the G okay uh we will create also this event listener with a function I will explain it in a bit so document. add event listener okay parenthesis it accepts as you can read here listener document event it will accept the kind of uh event it is a key down okay it is a key down and a function as a second parameter and this function we will create it to make possible you know to register this key press Etc let's call it on key usually when we create this kind of function we we call it on and the name of you know the action or the function that we want to do so on down always C case uh it has it has three parameters so yeah the key down the type key down listener uh also the function and uh options that is a bullan yeah let's leave it false the options okay so we have this event listener Kida let's create this function here on kidal function uh when a key is pressed execute this function okay function an okay a parenthesis it accepts a parameter that is the event if you want to to to to know more in depth about uh event listeners go and check mdn or the other resources so we have an event here as a parameter and this event uh will make us possible to access you know the event which we are triggering in this case our keys when we press the keys for this let's create a because we need to to to get what keys are we pressing how do we know we want to know uh from the code that this Keys have every key has a code in JavaScript okay so let's create a variable first uh key code let's call it key code and this variable key code will be event this one that we are accessing that which what is this this is to make possible to get the codes of each key let's search Google for these codes because I don't know I don't remember I cannot remember so key code tables yeah okay yeah I have clicked before for uh here we have all the key codes so as you as you can see enter is 13 uh shift uh Etc okay we need this one the errors so 37 38 39 and 40 so we need this we want to move the cube or the camera uh left and right so so we need this one these are the codes that uh do the work for us so we saved it in a variable evan. ttch and here we need the ni statement to to make possible to you know to get this the first one the key code which one uh 30 30 30 37 and 39 okay so 37 39 the right and the left the right is uh 30 39 right arrow okay let's uh make an if statement if key code this one here so if evan. which and this uh gets the code of all the keys okay so if key code equal 37 what's 37 was right or yeah it was left okay or let's start from the right if key code equal 39 so if the key is the the right arrow what we want to do we want to to to change the position of the cube or we can do another thing we can change the position of the camera we move the camera because when we will have the the player the player when we will enter the gallery inside uh we will not have a cube but actually we will uh like we have a a first person uh player that will enter the gallery and it will move around you know so for that we can use the camera so as a camera we can go like a PO view so we can move around so camera dot translate X okay uh let's move it a bit like uh like it should be positive for the right it should be positive yeah so 0.05 okay camera. translate it works it works but as you can see uh I press the right key but it goes it goes to the left uh why because uh it's not the cube that is moving so it's uh the positive number is the right if it was the cube but since we are moving the camera so we move the camera on the right we will see the cube on our left all right there it's logic so that's why so let's change it here negative number so we move the camera in this case on the left and by moving on the left the cube will go to the right or we will look like it moves but actually it's the camera moving not the cube let's let's try it again so press the arrow okay great so we press the right arrow key and it moves nice so the the same thing for the left uh error it was 37 so another uh another if so else if oh why a comment okay let's set comment for left AR key left AR key L if elif in this case elsf key code = 37 again comma uh camera. X because we are always uh on the x axis translate X and this time will be a positive so 0.05 Let's test it press the left we go to the left even though the negative is the left and positive the right but we are moving the camera as we said it is working until now so it's good sign we are having no more errors uh what else uh yeah up and down so the y y axis let's check for the the up arrow is 38 and then the down is uh 40 so 38 and uh 40 um up right yes up up Arrow key another else if if key code is 30 oh my God I I forgot in in a second and I forgot uh 38 okay again camera. Translate not X but Y in this case and the same Movement by 0.05 okay and for the down keyy another else if if key code equal 40 if I'm not wrong yes 40 camera. Translate Y acccept this time is negative 0.05 Let's test it so up okay I press up and it goes down so it's uh it's the other way around so here negative number and here positive okay press up okay goes up press down okay it goes down great it works so for now I think it's it's it's the same thing we can do with rotations yeah as we did uh yeah this is the idea uh I promised you that even if you don't know about uh event listeners you would understand in intuitive way right I hope so so pretty much is this uh we have this function on key down we call this function function in this event listener okay so we get access to this function to this event event. wit this event. wit gets the the code of this keys that we press and we call this function every time there is some trigger every time we like we have a listener there like it's like the name listener we have a listener what we want to listen we want to listen every time uh someone uh presses a key in this case because we are listening to a key down event so we are staying there and looking who is pressing the keys we will catch it okay so you are pressing the keys we are listening to you and every time you the the evant triggers uh we call this function onal when we call this function when we execute this function what we do if the key was 39 we move it to the right if the key was 37 we move it so every time we execute this function this is uh the idea I hope and I think it's easy to understand as I promised at the beginning so as you see until now 3js if you know a bit JavaScript it's not that hard let's say it's very intuitive the the names of the classes the names of the properties are you know are they tell something what they do so you can have an idea when you use those classes functions methods and properties uh I think uh we can stop here uh the moment so this is the code that we we wrote the last time we don't have much here we only have like a cube uh okay this one we only have this Cube I hide it the HTML here because I wanted to to show the cube last time okay so this is the the interface with this vangog painting some description information about the gallery and that's it for now I will hide it since okay this is an HTML element it's hiding the scene in 3D later we will do it uh dynamically when we click when we start we want to show the the gallery then when we pause or when we press a key we want to return to to the main menu okay like play or false so let's hide it again go at our main file so uh I will start with the floor the plane okay so we need the plane the ground and uh we will apply some texter to it to make it look nice and let's see let's see maybe then the walls uh the sailing let's see together so let's find a place where we where to start the new code okay so here we have the controls Keys let's let's start here above the controls keys so wait this okay so let's start with the floor create the floor it will be a plane floor plane come on it's my my co co-pilot it wants to suggest okay uh the floor so to create the floor if you remember in the last video we created the cube and for the cube we created first the the geometry of the cube we created a box geometry here it is so geometry new three box geometry and uh you have the comment here box geometry is the shape of the object then we created the material and the material is the color of the object the look okay then we create a mesh we called it Cube so this mesh accepts two parameters the geometry and the material like it creates this uh new object 3D object that has the geometry and material like merged okay so we will do the same thing with the plane with just small difference so L let uh plane geometry okay I think you remember here what we we should right so new always new for a new instance of the class that we are going to to to take so three uh this time not box geometry but we want the plane geometry intuitive right so Lane G geometry okay and it accepts two parameters we can go to Google and check if you want so 3. plane geometry okay here's the documentation a class for generating plane geometries yeah what we need code example yeah this is what we wanted to do create the geometry first then create the material then the plane that is a mesh that accepts geometry and material okay easy peasy then add this plane to the scene the same as we did with a cube that we have here in the scene okay so yeah we can copy this but we want to do it ourselves it's always good practice to always write down manually not copy past it of course copy pasting is helpful of course we need it sometimes we need to be quick but when we are learning who who for those who are beginners but even for those that has experience they are always learning something new at the point so when you are learn learning something new always write down the code it it creates this habit it then after a while it it it it becomes a second nature okay when you write it by hand by typing because when you make it a habit like to copy paste the code or you know use some kind of just a syntax help uh yeah it's very easy to forget even the most basic things like oh I need a map how to write the map or I need a function how to write the function or how to write the the component in reactor you know for everything it's it's normal it's normal I think it happens to everyone so without much talking let's create this habit of writing down but yeah the idea is this I wanted just to check for the parameters uh what parameters I see there are two parameters here I think it's wide and width and height let's check so width uh height width segments and height segments so it accepts four parameters this two should be optional yes they are optional so the first two that are important the width and the height okay let's do this okay let plane geometry new three plane geometry two parameters we we set so I don't know one was the default one yeah was the default one let's put it 50 for now who cares uh let's leave the optional parameters for the width segments and the height segments uh so in case you forget I will always write down the comments soof box geometry is the shape of the object okay so we have the geometry I think you remember now when you make this Habit to repeat the things again and again and again it will become hopefully a second nature so we need the material now so let uh plain material uh equal new always new every time you create a new object a new geometry material uh you know you will have this keyword new new instance of that class it's a new object uh don't care for now about the object oriented programming what's happening inside that uh you know parent and the classes you know three etc etc that we are instantiating don't care about that just think about a new I want to create a new geometry I want to create a new material and that's it for now at least uh so new three uh material right for material we see here it's mesh basic material okay so this one yeah I said we don't copy okay Mash basic uh okay suggesting yes we accept the suggestions so meas basic material it has uh the parameter an object and inside this object uh we put some properties key values right so open parenthesis and this object inside this object it will accept some properties uh for the material we said that it's the look of the object so the color this the simple color we will learn uh now in this video about uh other uh look of the object so not only the color the simple material but also adding the texture so you know customized uh look so we will give some image that we have etc for now let's create this uh plane that will be the floor of the gallery with a simple color just to to see that object in our scene just to render it so for that I think you you had in mind that we need color and let's give it a color like green okay uh another parameter it's here yeah it's optional but it's side and the side it's double side okay double side I will explain what it is this is to render both sides of the plane so yeah we created uh the geometry and and the plain material right so I want to ask you again I mean ask you you know just stop the video and maybe try to to to do it yourself what what what we need we said before when we create a new new 3D object we create the geometry and the material then in the end stop the video if you want without checking and uh try to remember if you create it that you know that habit so we need the mesh the mesh that we we pass the parameters of material and geometry so for that uh let floor or floor plane okay equal new always new three mesh parenthesis and it accepts the plane geometry and the plane material right plane geometry plane material that's it yeah uh yeah I would like to ask you again do you know what we forgot here what else do we need do we see uh no we don't see anything we forgot to add this floor plane that contains the geometry on the material to the scene for that simply writing scene. open parentheses and floor plane right that's it let's check if we can see anything yes we see it you see it looks like a background really not really of the floor of our Gallery it has nothing to do with the floor but yeah we will we will we will go there we will go there for now it looks like the background we added just a simple material a GRE one okay uh to give it a better look I mentioned before that there are no not only simple materials but we also have the chter okay so for chter we can add let's say something ourselves an image texter that we we have because texter are images that will cover the surface of our geometry okay and uh many many types of these textures can have different effects on the appearance of our geometry so it it is not always a simple material simple color we have like different types of of texures we have uh the color one or albo sign 3D softwares you will see albo the albo text is the the the most simple one it's you know it only chees uh the pixels you know and apply to to to the geometry uh then we have some other types like Alpha I think you also know Alpha part from albo that is the gray scale image and uh you know for the transparency it it it where white will be visible and black will not be visible then we have some more complex cheers uh we have the height Checker the high chter will move the vertices to to to create some some relief uh but yeah I will not stop here at the height we also have the normal uh that is also common used uh the normal cheers we add small details in the texter you know we it won't move the vertices okay but it will create the this feeling of of the light thinking that is is is the face is oriented differently so they are very useful and they are used uh often to add these details and yeah give that look of performance uh 3D object uh yeah we also have some other Checkers that I think you also know or heard or you s somewhere that is the the met the metal the metalness chter you know is that gives that look of uh metallic you know there is also the roughness that again we use it to to to to make the part rough and it's like with white and black the white will will give the part that is rough and the black will make it the part smooth yeah there is much to learn about cheers I invite you to go and check the documentation do your research it's interesting uh but yeah we will not stop here maybe there is to mention the PBR that I want to mention PBR because PBR now is you know it's everywhere in the most advanced uh 3D softwares because now PBR is becoming the standard for very realistic renders so Unity engine which I love my favorite uh tool ever Unreal Engine that is also great uh blender and many other so they they are all using PBR now as a standard you know for realistic render for now let's add a simple Checkers that will be a checker yeah that we find somewhere on Google or you have it I don't know I already have I think the Checker I yes I have the Checker here is this one you know a text her about the the floor uh yeah we want this in our Gallery you have seen the video so you know this you have seen it let's try to add this one how to do it let's see where we left where we left okay create the floor plane we are here so we need to replace this color with a checker not a simple mag material like color maybe above or okay here for the texter uh we need to use another class that is called texter loader this texter loader makes make it possible to to to to load an image that we we have like in this case our our image that we have in this folder here okay so the class is Checker loader we can Google about it we can Google about it 3 texter loader let's check the documentation class for loading a texter this uses the image loader internally okay okay so the syntax is const tter new three Checker loader. load or we can create a variable here for this separated so text loader let or con texter loader this uh new three then texter loader. load you know to have a cleaner code let's let's do it here uh so we we will go we will go for for what I said for texter of the floor okay so let texter loader new three let's check again was it new three checks the loader okay three check the loader was it lower case no it was other case you see this small erors okay now that we have this variable Checker loader we can access uh yeah this do load and add our image right it's just the same thing but yeah we keep it let's say cleaner with variables so text load do load right and check to load that load and we have Checkers and the path of uh of it uh the path is IMG then floor let's try IMG floor. J right should be okay I think so I don't see anything let's see the console look consider using plain buffer geometry for lower memory footprint okay yeah because now three have this buffer geometries maybe I I will explain it later the difference it's the same thing but yeah it was the old use was using you know without buffer now everything is buffer because yeah it it's a better performance for memory Etc with buffer you cannot manipulate you can but it's uh more difficult to manipulate vertices Etc but I won't talk about it now but uh I have nothing I don't see nothing okay yeah we don't have any error I think we can add it to we can yeah I think the that is not an N is just a warning about this plane yeah let's buffer let's see if it is okay it is not anymore there okay guys I was talking about before about the geometry and buffer geometry okay that I mentioned before that I changed here the plane from plane geometry to plane buffer geometry they are the same thing not the same thing but you know we will do the work but they have some difference let's say the difference is that buffer geometry not just geometry is the newer one in the 3js library okay with there is some years that we 3js had this update with buffer geometry and I will explain the difference now and I will explain why this bug that we couldn't see I think I got it why but I will show you you know to have this process thought to to to catch the errors because yeah this is our job to deal with with bugs and errs so what's the difference okay let's see this one I already checked this so I think so the guy here on stock overflow is is asking what is difference between box buffer geometry versus box geometry in 3js the question that we also have so the geometry classes are manipulated friendly memory unfriendly all JS geometry classes okay they are memory unfriendly we we learned that uh this means that each piece of data that defines this geometry is stored as an instance of some classes Vector 3 Vector 2 Etc these come with convenience methods so you can dot a Vertex with some other Vector translate vertices modify Etc something that I wanted to do before this project and that's why now I have some problems I will explain better please don't uh get confused I will explain everything but it has overhead in memory and performance creating all these instances and storing them okay so B4 3js has these classes of geometry only geometry not the buffer geometry now now it's been a a while I don't know how how many years but I don't know two or I don't know now everything is replaced replaced not really replaced you can still use this with older version but now 3js has updated to buffer geometry and buffer geometry classes are performance friendly geometry classes that rely on typed arrays to store the data okay in a webgl friendly format so they will use a float 32 array okay the guy here explains the difference what this means that vertices instead of being an array of vector three they are typed arrays okay they are typed arrays and they are much more efficient yes sure they are much more efficient but much harder to manipulate something that I wanted to do with vertices I wanted to manipulate and I I had the new classes of buffer geometry I I had no information about this thing that with buffer geometry I couldn't manipulate Vector three and vertices so I was having some problems I didn't have the information you see the difference look at the difference here so I will I was used with this method with the geometry without buffer to get vertex five and have access to its you know this is what you do and this is what you do with buffer geometry you see now the difference okay this is a problem that I had with another project and uh there was a discussion uh by the guys the that created 3js I think it's here yeah the upcoming release has this potentially breaking change the class geometry will been a longer part of the core and yeah it was deprecated in this geometry but as I said since I wanted to to manipulate this vertices with another project I uh uploaded the older version without the buffer so only with geometry so the older three object you know this the older one that has also geometry not only buffer geometry okay because I wanted to to do something else with vertices and yeah uh why so much uh explanation because here I think is the problem since I had this other version to use geometry instead I think this class uh three Checker loader wasn't in the in this let me check something else image yours okay and I have this one this now is deprecated with the new version this three that image youtil was used before this texter loader so you see in the 3js modules the big object in the source code of fjs there is this this class of image UTS and now this is duplicated since I have it here that's why the problem let me try just forget this guys I think I found uh the problem just forget about this don't get confused so instead of instead of where was it Checker the Checker okay here let me try something I want to try something else three image toils okay this is the class that I just showed you not it's not parentheses let me check again please three source code uh you don't have to do this you don't have to dig in the source code of 3js three image TOS okay three IM major deals load texter now we have the the the parenthesis for the path of our image so the path is IMG uh Slash l.jpg okay so new free image yours load texter I want to try this floor texter M floor texter I want to try this let's hope yes AA a Rea we found the bug it was a hidden bug it back but yeah this was the reason guys why I had all that talking before about buffer geometry and you know since I wanted to to create something else I wanted to to to manipulate the vertices Etc you know you you you saw here in the stock overflow the guy that was talking about that is much harder to manipulate it with this buffer geometry you see it is much more performant and memory friendly but it's harder for you know some other manipulation and it's it was easier with geometry that why I changed the I changed this uh source code of three I got this because yeah I could yeah sometimes with three you can play play yourself a bit so now no more talking about this we found this problem you just forget if you are using the new version uh download it from from GitHub if you are using the newer version you should have this one so this class Checker loader so you you can use this code here so I'm leaving it here okay I will add a comment here uh image utils is deprecated in the newer versions of 3js okay I'm leaving it for now because yeah I want it this way I want it this way so it's not a problem in the end so I I I will use this image utils but usually you know you you can use with a newer version Checker loader is the same thing so don't get confused again we have uh this floor that we created the geometry and material in then create the mesh that takes the geometry and materials and create this floor plane but to not have a simple color green that we had before but to have a custom image texter we created this texter that for to create the texture you need to create a new instance of this class texture loader or in my case image TS okay guys I hope it's not confusing I will leave the code like this the good news is that we can see we can see this our text are even though it's blurred and you know we cannot see but we see something that's a good news now let's try to to to modify and correct things with this new Checker and with this new plane that has this Checker okay we have addited in our scene no before here before uh we want to move this floor because you see it's very blurred and it doesn't look good we want like you know in the vertical axis like you know just the ground and we we we see it that way okay let's try to to do that so we need to rotate a bit this this uh this floor and to rotate there are some mathematics but uh don't worry we will not do Advance math we will use uh some internal methods that will do the the calculation for us okay so no advanced math for that to to to rotate the FL Flor floor plane do access rotation rotation do X we want to move it in the x axis oh that x uh I want to try to move it like 90 degrees okay and how you do that how you can move 90 degrees you cannot like write 90 here to do that we will use the the math. piy internal method okay so math. by divide it by two add the comment uh this is 90° rotation so if you want to to to to rotate something 90° use this formula uh formula math Pi ided by two okay uh let's see if we have we don't see anything now but we don't have any errors right no no errors but we don't see it uh let's uh floor plane do rotation. ya AIS this time and uh to rotate it in the y axis so not the the X but the Y we will rotate it uh 180 degrees okay so if you see that divided by two is 90° we can assume that for 180 de it's just math. Pi not divided by two right M that P this is uh 80° we don't see anything yeah I love errors I love when I have errors you know I forgot something here four plane four plane four plane where is four plane okay four plane it's correct okay the problem was the rotation I think I got the the AR where is the problem I think so so FL floor plane rotation X it was correct actually math. Pi that's it I made it's just a small mistake that's why I am not seeing the four so again y math. p okay so this was before and we didn't see anything okay the problem here was just a small detail for the y- axis not rotation but position AA position let's check now okay we see it finally even though it's upside down but we can correct it quickly so since it's upside down let's put a minus sign so minus 180° okay okay finally and that's it AA I finished this part here I had in mind to to continue with the walls but I think for this part I am finishing here okay and that's it we have our floor you see now we miss only the walls the ceiling and then we can modify the shape of this Gallery wide or you know then we can think about uh the paintings and give that very looking good that we have in the video okay that was the problem we couldn't see it because it wasn't I I finish this video now I will try to upload the other parts upload I mean I will make the tutorial and upload I will try to to to do it as soon as possible so you can finish this project so thank you very much for being with me and let's see in the next video bye and this time we will try to create the gallery walls uh as we did the floor last time uh okay I have opened my visual studio so without wasting time we can start by creating the walls so here is the code that finishes okay floor plane we created the floor here so below below we can start the code about our so let's add a common create the walls right for the walls uh since we we are going to create more than one wall so we need the front wall of the gallery we need the left wall the right wall and also the back wall and in the end we also need the ceiling we have the floor we also need the ceiling so since we need more than one wall we can create a group of objects uh 3js has this class of group when we want to create a group of objects that we know that they will be in this group you know to manipulate them together or we just want to recognize them you know for like in this example the walls like front wall left wall right wall and back wall there will be in this group so let's start by creating a group of objects okay uh I notice here I I used let and const so maybe we should be consistent and use yeah const for this thing the things that that aren't going to change like these variables for example yeah renderer cameras saying they are not going to change geometry also it is not yeah we can use const here but just to be consistent const cost okay yeah Sal andent light okay so this is our current scene what we what we have you notice that we can move the scene right we are actually moving the camera because at the beginning when we didn't have the floor we had the impression that the cube was moving okay we press the right arrow and the left Arrow the cube goes that way but now that we have the floor we can we don't have this impression anymore so we see that it's the scene moving actually it's the camera moving okay later we will change this and we will move the player the the person that is going to is entering the gallery okay let's go back to our code we are here create the walls make some space so let's create a group of walls const Wall Group equal three. group parenthesis uh leave a comment here create a group to hold the walls okay let's add immediately this group to the scene so we don't forget later so let's add this group to the scene scene. add you already know I hope this by now to add things to to the scene after we create something we add it later to the scene so scene. add Wall Group and this is done now let's start by creating the single walls so let's start with the front wall we enter the gallery we have the floor we will have a front wall in the end okay so comment front wall and again uh what what we'll choose for for the walls we used we use the plane for for the floor the plane geometry you might think that we can also use the plane geometry for for for the walls but we can use a simple box geometry that we already used many times right now so box geometry and also a simple material to give a color to it just to recognize in the scene the the wall okay we will create this box geometry but you would think that the Box geometry will be like you know like a box we need the wall but yeah but we will create the box with the width and with height but you know on the on the Z axis we will make it like thin thin very thin okay so it will be a wall am I explaining myself so const front wall equal new always new keyword to create something new three uh we can create like we did the last times we create a variable for the geometry we create a variable for the material and then we create a variable for the 3D object that is a mesh geometry that has inside the variables of geometry and material or we can use it in a code block so we can use a single code block to like this just to to to make things different so you you get used to to it to this idea you can use it like up above with creating a variable for the geometry creating a variable for material and another variable for the mesh that contains geometry and material or directly create the mesh having inside the parameters okay and with a main variable like this directly let's see it in action so front wall new 3. mesh okay parenthesis now let's create the geometry and the material so new three. box geometry okay open parenthesis and the parameters are the the three parameters for X for y and for Z the you know width height and depth and you know so let's give it like uh 50 20 and yeah we want this thin very thin we just want to to to have it you know the width and the height but thin not like a box so 0.01 or 001 let let's see it okay comma and now we will add the material you see they are in a single block of code not by creating three variables you can use it either one or how you prefer but I want to show you you know to get used to it new 3. MH basic mat iial uh parenthesis and this accepts an object with some properties that we can add so object inside this object we have the key value of color green red blue okay so the property of color and the value of uh let's make uh each wall a different color so we can separate and recognize that because if you if we make like red red red you know we don't see the the borders you know so let's make every each wall different color let's start by Green okay and we created the mesh of the front wall do you remember what we need after we create the geometry and the material and the MCH containing this geometry and material uh I think you you remember it we always need to to add this to to our scene okay do not forget because if not you will not see it in the scene but also we need to to position somehow this wall because we want to see it you know but first first uh let's try to add to the scene so to add to the scene we will not use scene that at in this case since okay you see here we already added this wall group to the scene okay so the group containing these child okay these walls will be added to the scene since we added the group there okay so if we say for example W group. add and we add here the front wall then we will have the left wall right wall etc etc so since we are adding this front wall to the group Wall Group here it will be automatically add the to the SC since we added to the scene the Wall Group I hope I am explaining myself uh yeah we can we can try and experiment live okay let's see what's the error 3D object. add object not an instance of three objects 3D undefined okay okay let's check so Wall Group 3. group uh first of all we created this this this group okay and seeing that add Wall Group we added uh the Wall Group to the same we are okay here then then we want to add this front wall to the Wall Group okay so wall group. add front wall and is this one here okay uh I forgot the keyword new that's why it's not an instance of okay forget it so it should work now yes okay okay so we have the front wall but we have it you know to Too Close and but we have it so we are there uh very easy very easy now we can change the position you I hope you know by now to to change the position and have clear this idea to to change the the position in different axis on the x axis y AIS and Z AIS so in this case the front wall it's in front of us okay so if we move the position in the X AIS it will be still there to close but just moving left and right if we move it on the y axis we will move it up and down so what we need in this case with the front wall is just push it and you know give it some space we want to push it forward and that is the Z axis okay so the depth we want to push it forward so let's change the position on the Z axis because I think the left and right so the X and the Y let be on the Zero you know this the by default we are not going to change it we just need to change the Z axis let's try so here front wall that position Z we said and give it a value of so as you know for the x axis uh positive number is right side negative number is the left side okay zero is the center so if we give a value of positive number uh the object will move will translate the position to the right if we give it a value of negative number we will move it to to the left so the same with Y and the same with Z in this case if we give a positive number we will have it to close so in this case let's try with a negative number okay and the negative number of uh I don't know 10 let's try it okay 10 looks looks great because maybe I think we gave the of the floor we give the same value of 20 as the height or you know whatever 20 20 is is uh looks looks okay so we have this front wall of the Galler of course we can change the values for the width it looks perfect for the width it looks okay we will match it uh with the width of the floor we will check but I think it's 5050 because I I remember that the floor was uh 50 as the value so also this wall here is 50 and it it matches uh for the Y it looks okay maybe higher I don't know but it looks okay for now higher will be to much maybe I don't know we can always turn turn back later let's leave it like this we added the front wall let's start with the other wall the other wall yeah the left wall left wall so again like with this method above create a mesh that has inside geometry and material or create separate variables for the geometry separate variable for the material and then the variable of mesh containing this as you prefer I'm trying to do things differently so you get used to to like the idea so const uh variable left wall and this variable will have this instance of the class mesh from three this is uppercase three is always uppercase three do mesh parenthesis accepting two parameters the geometry don't forget the keyword new as I had the problem before when you instantiate a new instance you you you you need the keyword new because you know from object oriented programming for example this mesh class uh in the you know in the back scene would have a con Constructor with some properties you know we get some properties from this class okay but they these properties of the Constructor are Dynamic so they have a key that we can give a dynamic value to it for example so the mesh has some properties defined there and we can just give new values every time time we create a new instance of it so for example this mesh class would I think would have a Constructor normally it has a Constructor with some properties defined there uh we can give to these variables these properties uh Dynamic values every time we create a new instance so that's why knew this and knew that okay we just create a new instance of this mesh class that was defined there with its properties okay but every time we create a different instance with different variables we get a new one a dynamic value for these properties okay without confusing anyone let's continue with new uh yeah the geometry right yeah geometry new three uh do box geometry again parenthesis uh let's give this value again for front and from from left let's try it with the same values the same width and the height and the Z axis so 50 20 and 0.1 comma don't forget comma here and the next parameter which is the material new three do mesh basic material it's the simple material parenthesis it accepts an object inside and inside this object we can put some key value like color red color green Etc we have green the front wall let's give it another color so red color red okay and now after creating this uh I think you you know by now we need to add to the scene so left wall add to the C and it should be okay okay we need to position it but let's see first yes we have this left wall but as you can see here and as you can imagine as with the front wall it is again in front of us with front wall we did nothing but just pushed it forward in the Z axis okay but what we can do for the left wall because the left wall we need it like this you know like in a vertical axis so we need to rotate this this wall from here we need to rotate it like this okay so like this so we need to manipulate the rotation in this case uh not the position we need to just manipulate the the rotation of course the position also we we we will give that value but most important here is the rotation so from here here is like n sorry it's 180 80 degrees okay so no yeah from here here we need to move it no sorry it's 90 degrees actually yeah here it's 90 degrees because 180 deges will be like the floor turning again okay so it's half half this the the the sphere so we we need just 90° in this case and 90° if you remember the the last tutorial for for the 90° we can uh we can use math. Pi ided by two formula okay when we want 180° we use math. Pi 90° is math. pi divided by 2 so 180 ided by two let's try that okay here left wall left wall do uh rotation rotation okay so rotation in the Y AIS right's try so math. Pi Pi is uh uppercase uh divided by two this is 90° let's see what happen what's happening we cannot see it okay because we we we rotate it but we cannot see it it's not in the scene we rotated in the y axis it's not in the scene let's move it let's move it uh let's move it in the xaxis I think we cannot see it because let's move it in the x-axis don't don't don't get discouraged guys we will get there so let's move it in the x axis okay left wall. x. position position. x equal uh in this case if we said the positive number is the right and negative number is minus okay so negative is left positive is right so we have the left wall negative negative negative again negative 20 let's see what's happening oh error okay cannot read properties of undefined reading position when you see an error like this usually it's like the property that has this position doesn't exist or there is some problem there is some error with it okay so we cannot read the properties of undefined so position is a property of this undefined what is this undefined this undefined is X of course because you see position of undefined undefined here is the x that I don't know why I wrote that it's left wall. position. X not left wall. x. position. X okay but yeah you you should get used to understand the errors what they mean really you get used to it when you get often bugs and errors like me I I get a lot as you can see I make mistakes but I hope that I also learn from them but you should get used to the meaning of this errors it's like those very important things in programming and for developers yeah it has some meaning so it was undefined yeah we see the wall and it's perfectly fitted we okay that's great that's great you see we also have the left wall and this property here was perfectly I just want to try not math that uh pi divided by two but 180 degrees and you see as I said one math. Pi like make a rotation 180° okay so it will turn again from the other part okay like back in this case we need just a 90° from here here 90° okay it's like this I think you have this clear but you can always play you know if you have problems in other projects so divide it by two and the position was the the because if we try this not negative but positive you will see it now at the right the same thing that we will do with the next wall so okay you see it's on the right side but since we named this uh left wall we need it with negative number now we can easy peasy create the right wall because it's the same thing here we can just copy it but we said that we don't copy we manually type because we want to create this practice and habit so it becomes with practice second nature to to not forget how we write code call things functions methods Etc properties left wall now comment right wall and con again right wall equal new instance three main object mesh class parentheses and mesh class has these options that we get from it ready made it's properties that we give a dynamic value every time we create one we we we can give another value different value so the first one is the parameter for the geometry so box geometry uh new oh new okay you see this small errors but they can create a bu three. point geometry all the geometries are are always from the main object three okay so three is the main object I will I will show you here this is the source code of three you see there are how many lines okay we have like more than 355,000 lines okay full of this classes methods Etc so VAR three this is the main object and then inside this object we create classes with Constructors with some properties that we have defined there that we can give new values every time we instantiate and create new instance of this classes and this uh classes may also have methods that aren't anything else that simple functions so methods are functions declared inside an object and we access them we access them like mesh dot. function so it is called the method and yeah you know three is the main object here that has inside all these classes like mesh that has these parameters that we can pass geometry uh value again 50 20 and uh 0.001 comma don't forget and new uh three again mesh basic material parenthesis it has an object inside this object has some properties like color with value uh yellow this time we want to differentiate those colors yellow good so this one is easy peasy because it's the same with the left wall so but we don't copy left wall. rotation again the same thing oops rotation Y is it y or yes y math. Pi formula to rotate we will always use this formula oh my God this word is so difficult for me we we will always use this formula for rotation 90° or 180° 180 Dees is math. pi 90° is math. pi divided by two we want this 90° so math. pi divided by two and again I will leave a comment every time so it will stick in your mind this is 90° I want to make it stick in your mind and position left w. position uhx equal not minus 20 but 20 positive number positive is right and what else here guys yes you know we add it to the scene and we don't do scene. add we do WG group. add because Wall Group is already on the scene so we we just need to add the Wall Group on the scene and the Wall Group will add everything that has inside as parameters pass here right wall and we don't have any more errors no okay we have again the wall but I changed the position position why um rotation y ma ided by two and position is 20 then why what this happening here do 20 are okay where wall right wall Warrior you are on the front what am I missing here guys I think you you are quicker than me to find the arrows I'm sure left that position that Tak oh my God okay okay I you you I I am completely sure that you of course you you saw this this this stupid error from me right I wrote here I changed again the position of the left wall the same thing I did here it's the right wall right that's why but yeah we learn from the errors let's check okay good we see it we have different colors you know we will in the end we will give White Walls to this but if I make it white we we cannot see the difference because also the background is white and we cannot see we just see just a big white well okay looks looks good until now so what's left it's just the sailing right we just need the sailing now let's set the sailing right and the sailing for the sailing uh do we need to create for the sailing in the same group here that we have this guys here the walls no because the sailing will be separated from this as it is separated the floor the floor was a plane geometry right so it was not in this group of walls so also for the sailing we will create a separate 3D object okay and not a box geometry but this time again like with with the floor we we will create a plain geometry So Below this okay sailing so again the old method we create a variable for the geometry we create a variable from for the material and then we create a variable for the mesh that contains this final object okay or you can use again mesh inside let's keep things different so you get used to it once you get used to the idea how it works behind the scene you have it easier to to develop things so again with the old method with variables so con uh the geometry sailing geometry equal new three that uh this time plain geometry and plain buffer as we said buffer has is memory friendly so has better performance uh is better for the memory and you know it's the new new 3js new plane buffer geometry uh we had 50 here for the width 50 for the width so the sailing will have also 50 for the whe but yeah also 50 for the y axis let's do it 5050 5050 okay I will I will not get charred on writing comments I I will repeat the same comment every time we create a geometry every time we create a material it will stick to you I'm always uh referring to beginners guys so if you are someone who has experience uh don't laugh at me that I repeat these things again or don't get bored because okay I know that maybe you are uh good developer you don't need these things to to be repeated 100 times but uh actually I'm refering to beginners because yeah this tutorial was let's say for beginners not only but yeah so bear with me some passions when I repeat things so box geraty is the shape of the the object now let's create the material sink material new three object main object and mesh basic material class uh for material for uh the sailing we used the red green and yellow red green yellow let's use blue for the ceiling so do you remember inside the mesh basic material we have an object and then we have this properties of color or blue Double D dou do okay we created the sailing what else we didn't create the sailing because to create the sailing you create it with a mesh so const saling linke equal new three main object mesh class and uh pass here sailing geometry and sailing material okay now we created the sing but we cannot see it of course we cannot see it because we should add it to the scene as we always do so seeing that that uh what's the name sailing plane okay now we should see it but again we need to position this sailing because yeah I think we will see it again in front of us yes we see it again in front of us so yeah it's another object that we see in front of us because we need to position it so for the other geometries we rotate 90° like this or 90° like this so 90° and then position it to the Y axis minus 20 or positive 20 this time we need to rotate it up above so we need the sailing like like this rotate like this so can you guess how how we can do it want to try it yourself maybe okay how we want to to to to to rotate this on the Y AIS uh not not in the y axis because in the Y AIS we did with the with the walls so it should be in the x-axis let's try let's try I hope I'm not wrong on the x axis but yeah let's try let's try so ciling plan uh rotation mod by ceiling plane do rotation that let's want to try y maybe first I think it's X but well let's try how we see it with with with Y AIS uh sailing plan rotation. y math. Pi Pi is always uppercase divided by two 90° this blue hurts the eyes that by oh oh I was seeing that is like a bit rotated and I was wondering why uh you see but uh yeah I divide it by two not by 90 we cannot see it because it's not uh there inside the the scene Let's uh move it a bit in the y y AIS so we see it sailing plane. position. x uh let's try 20 we cannot see anything 50 we cannot see anything 20 10 we cannot see anything so we rotated it in the y axis so let's try x axis so 90 Dees in the x axis again we cannot see anything 15 I cannot see anything Rotation byid by two oh we have x x you see the RO the rotation will be y not where around so the rotation will be Y and no not y y was for the walls the rotation should be X and the position should be y okay we see it we should move it uh down so in the Y axis so 40 no 13 no 12 okay fit perfect we also have the sailing we complete this looks nice yeah but one thing I want to do I want to do something because uh later when we will will create the player and the player will go around the gallery when we go near the wall we want to have a collision we cannot pass through the the wall okay we cannot break them through to the other side we want to have a collision and stop there because we are not ghost we cannot go uh through through through the walls so for that we will add the collision and to to add the Collision uh there are some ways and they are different from program to program from 3js or Unity or in real but the idea is to add the collider the collider is you know like uh bounding box that it's the same as the object that we want to add that collider okay so when we go near that object we collide with this box collider and so we will stop there by adding some other coat okay but the idea is to add this collider so later when we will create the player and the controls to move right and left we want to to stop when we go near the walls so for the walls here to create this bounding box first of all let's loop loop through through this walls because we want to add to each wall this bounding box okay so here let's Loop through each wall and create the bounding box okay so a for Loop uh array. length it will be not array. length but it will be W group W group. children. length so the W group that we have that has the children that are all the walls left right and the front so Wall Group do children length Okay so we are looping through through this walls and to add the bounding box we access this B box B box 3G that is okay so equal so w group children I that is the element each element that b box equal new three boox 3 okay this creates this again we need W group. children I element we will will use another method here we will use another method here that is called set from object and this set from object will pass this W group. children I let's switch this yeah this set prom object is to compute the bounding box of the children inside including it children so so to create the bounding box not of only one object like with B box three but when we have a group of objects we want to create a bounding box for each of the children in this group of objects for this we use this method set from object okay that's it and here it is we also have this bounding box for now we leave it here because we we will have to do with it later when we will collide the player with this walls but yeah this is for now we can finish this tutorial and see in the next one when we we add the paintings and yeah we will modify our scene make it look better okay see you in the next video and thank you for being with me uh the main changes uh before we we we we begin where we left uh is that I updated 3js uh with the latest release okay so now we have the latest release of 3js which is a good thing we always want to have the newest updates from 3js also I added a build tool which is uh V or vit I don't know how it's spelled but it's lighting fast you know if you know Vite Vite is a build tool and it's uh lighting fast to build uh the server to run our project so we don't have to you know go live here with the option or have the three file downloaded and uh have it here on our local as we we we had it before uh we will download three from mpm as a package I'll show you so search on Google uh 3js installation click on it as you can see uh here it says that we need the projects structure and first of all we need an HTML file which we we already have main JS file which again we we have uh then we can import uh import uh Star as three from three so import everything as three from the three package uh we also May create a public folder which is also sometimes called uh static uh here we have like all the files like the media files uh the 3D models uh assets uh and everything um then you need to to to run this commands so install three with mpm so mpm install D- save three it's to save this uh in the package Json dependencies uh and also for Vite or VD npm install uh VD run this command okay I already have it that's why I'm not running it now but you can find it on documentation and run this after installing mpm install three and V you will see you will have the a package Json okay and in this packet Json uh you will have this section here dependencies and Dev dependencies where you will see the version of three which is the latest one okay and also for V if you have any problem you can simply go uh on my GitHub check the link in the description uh copy this file package Json or download the whole project but if you want to follow along just copy this package Json edit it here in the root at the root level okay and then you can simply run mpm I mpm install and it will install the dependencies that I have here in the package as if you have any problem now we will start the features that we want to add this time uh if you remember we left it the last time we created the floor the four walls the ceiling and then we said that we want to create the paintings on the wall and also the camera movement like a user enters the gallery and moves around in an immersive uh experience way with a camera movement we will do that and also have the menu like we click the start the play button you know and then we can pause we'll see we'll see together first of all uh what what we would need first we need to import for the movement let's go to main JS oh also I forgot I also I I changed the structure of the folder now you see the not modules of course because we installed three invite so you will see not modules uh I added this structure uh folder SRC inside SRC you will see the folder public which we mention is for the assets media models Etc the HTML file of course the MJS for our script and yeah this CSS so and that's it you can yeah take a look here and uh follow as well this folder structure to be you know to have the same the same project or you can download from from GitHub okay uh as we saw in the documentation the first thing first after importing uh after installing three invite uh we need to add this yeah import Star S3 from three so here we don't need anymore this cono log okay we import everything at three from three and we will access it here okay so now this variable here three will be accesses everywhere here okay then uh we need to import the the controls for the controls we don't import them from the main three class main three object actually but from another import and I will show you we are talking about about Pointer log controls okay it's what we need pointer lock controls from three STD leap Library you need to you need to download this okay to install I have it here on my package Json installed you need to run mpm SD lib here okay run the command and uh install it or as I said copy the Packa Json that I have on my GitHub and simply run mpmi it will install all the dependencies after having this and importing it here we will use it later uh for the controls something else I I I I changed it's I I want to replace the deprecated image utils with texter loader I left a comment uh in my code there uh let's see image details okay it's here you see for the texture of the floor I left a comment here image yours is deprecated in the newer versions of 3GS now we have the newer version of 3GS we have the newest one okay so we will delete this image utils which is duplicated and we'll replace it with another class of three which is texter loader I will show you so here delete this part okay and instead okay up and instead create a variable Checker loader Checker loer equal new as you remember we always create a new instance of that class so new three uh textor loader okay it's a method so now create another another variable const floor texter and assign it to texter loader. load okay and here pass the path or the the URL of the image for the floor for the floor we we add an image here in Public Image floor. jpeg okay so here with v we use uh this way we don't uh type oh sorry we don't type here public Etc but we simply add come on simply at EMG slash floor. jpack okay of course it's a string like this not the absolute path like SRC public etc etc simply add IMG floor plane jpeg Etc okay and that's it now we have with the newest version of three we are using the texter loader and not any more image utils and this is fixed uh what else uh yeah we want to to to add the paintings okay so let's create the the paintings for the paintings we will create uh a painting mesh with a given image URL okay so a mesh with a image URL and also it's dimensions and also its position okay okay so let's create this function that will accept this parameters uh let's create it somewhere yeah maybe here after the the sailing and before the function for the movement okay so function uh create painting create painting okay and as I mentioned it will accept uh some arguments that we will pass which are image URL okay uh with also height uh position which are things that we need for our image okay open curly brackets and here we will create the logic for creating these paintings okay so inside this function we load the image texture and create a painting mesh so the complete function will look like this with this logic first of all we need uh a texture loader again so for that as we did with the the floor uh a few moment ago uh create a variable const textor loader okay uh as always new three text loader okay then we will create a variable for the painting texture so con painting texture okay that will be with using the load method from texter loader okay this is uh warning me that okay it's uppercase so painting texter will be texter loader. load okay and as a parameter here we will pass the image URL which one this one here that will be passed dynamically every time we will use this function you will see so here pass image URL and this is done now we create the material const painting material equal new three mesh basic material I think you remember the mesh basic material that we we we covered in the other videos basically we have an object inside and we use map okay and we pass the painting texture if you remember you should be familiar by now with this and also we create the geometry for this uh paintings so const painting geometry okay and the geometry is made using a class from three in this case it will be what kind of geometry it will be a plain geometry because yeah it's a plane so uh new 3. plane geometry okay this plane geometry we will pass two parameters width and height of course so width and height so yeah we will create the mesh now we have uh the texture we have the material uh we created the geometry and now we will create yeah the painting because the painting will be as if you remember from the previous videos you know that the mesh is made with the geometry and the material okay so in this case con painting equal new three mesh it's a mesh what we want and we pass as we said the geometry and also the material the geomet is the variable here painting geometry painting geometry and the material is this one painting material okay and this is done yeah we we have this function we need to return this function of course because we will use this function so it it should return what it should return this painting Okay so so return painting and this is done maybe maybe yeah of course we also we said yeah we we want to use also the position when we create uh the painting every time we will use this function to create a new painting we will also use the position we will pass a position for it okay so here before returning U painting that position and in this case the position will be uh first we will use set to set the position and the position will be this value that we will pass position uh that X position y position. z position. x positiony position Z okay and that's it uh for for this function create painting we created this function so what else with this function let's add the paintings to our scene to call every time this function we want to to create one okay so we will create for example two paintings now with different images and different positions so to do that we create create a variable for let's say painting one const painting one okay and we will call this function that we just created create painting and here we will pass first the path or the URL of the image uh I already have here a folder artworks with all the works by vangog so let's use some of them it's uh simply artworks without SRC public Etc artworks okay and then um yeah zero. jpeg Z okay the first uh parameter uh the second one width and uh height and also the position I will give 10 five here okay let's see and for the position we will create uh a new Vector 3 class for the position so we will uh create a new instance of vector three so new uh three dot Vector three okay and we'll pass uh the values for as you see here X Y and Z okay I don't know let's give some random one in this case uh but yeah for the X let's say just 10 minus 10 for the left for the Y uh positive five and uh uh for the Z let's give it 20 negative 20 okay painting one also let's create another painting we will put it at the front wall so const painting two call the function create painting again every time we will create a painting we will call this function okay it's it's very useful as you will see so create painting and again pass the arguments in this case the first one is the URL yeah artworks art works then one. JP okay also here slash I think uh the same thing but this time not negative but 10 okay five and also minus 20 should be okay and again for the position new three do Vector 3 and pass here uh the values for the position in this case again not minus but positive number it will be uh left and right so 10 5 andus 20 it should be okay now that we created these two painting if you remember every time we create an object a 3D object we need to add it to the scene because if not we will not be able to to to see it okay so I think you remember this scene. add to add the things to to the scene and pass paint painting one and painting two oh we should be able to see something I think okay we might have some errors cannot assign to read only property position of object 24 Let's see we don't need actually this line so we can remove it let's see yeah now we see something we have another error but yeah we can fix that we can see yeah we can see the scene we don't see the paintings okay we have a problem use them and we had another arrow uh okay let's fix this one first of all let's fix this plane buffer geometry has been renamed to plane geometry three module okay PL buffer geometry let's fix that first okay it's been renamed to plane geometry right plane geometry yes because now we are using the latest three JS so remove the buffer one okay Lane geometry okay this is fixed uh not found so yeah maybe the title is wrong floor plane yeah it's wrong it's floor okay now we see the floor okay but we don't see the paintings yet let's check oh yeah maybe it's let's try 18 yes so let's use 90 because I remember 20 was okay you can see 1999 yeah 20 is the limit okay also here can we see the other one we don't see the other one why artwork it's okay width height oh this one what is this it's not the this parameter it should be okay yes okay as you can see guys you see the paintings on the wall it works and we can use that function every time we want to create another painting we use the same method so painting three painting four painting five you know you can call every time just create painting function and create as many paintings as you wish we can of course create like function like to create like 50 paintings uh at once without like calling and creating manually you know painting one 2 3 4 of course we can do also that but we still don't know how many paintings we want to have for now for the sake of this tutorial we I will leave it here just these two paintings okay it's the same logic so maybe you have it as a small challenge yourself to populate uh all the scene with with other paintings okay so it's up to you in the end if always if you have any problem of course I will I will do it we don't have any errors right no we don't have any errors we are good to go so we want to create now uh the movement because we don't really want this movement you see I press the right arrow and I go left I press the left arrow and go right this is because initially we were moving the camera and had the feeling when everything was empty the scene we had the feeling that the cube was moving right and it made this idea we were moving right too but no not that we have other objects of reference we see that I press the right the cube is moving to the right but we are actually moving to the left so we will change that also I will have to add the keys W S A and D to move not only the errors but you will see that I will add this pointer lock controls basically you move the mouse and you move around in the direction of of of the mouse uh why we need that we need that because it will be smoother movement because I move the mouse I like look around and then I can move with the arrows or wsda a I can move the mouse and then move forward or in any direction it will be smoother and a better experience you will see so let's go back here so we imported at the top the pointer lock controls okay you installed this now uh let's use this uh pointer lck controls okay we create we will create an instance of pointer lck controls and connect it to our camera and the document body or maybe let me think a second because that's how pointer lock controls works we need to click at something and it will activate the lock so we click and then let's say the controls start okay then we presses in the keyboard and the control locks unlock meaning they are deactivated we cannot move anymore what we want is click the play button uh enter the gallery then we can move so we want to add an event listener to the play button to lock to start the controls okay and then uh n listener when we press ask they will be deactivated okay and in this logic we want to hide the menu after clicking the play button we want to start the controls but also hide the menu because we will enter the gallery but as soon as we press the ask key we will deactivate the controls and display again the menu so we will have the chance to play uh the button again you know so like play or not play let's see let's see uh for this so let me find a a way where we can add this maybe here yeah here before before the the function on Q down okay we can add that so uh control okay create the variable controls and always new the new keyword to create a new instance of pointer controls pointer log controls and pointer log controls we will attach the camera to it okay so camera and also the document body document body okay so we will click and we will uh activate this so we need to create function for that okay to start the the game the game it's not the game but to start our journey our tour okay let's call it experience so let's create a function uh let's call it start experience okay lock uh lock the pointer I will explain log the pointer uh meaning uh controls are activated okay and hide the menu when the experience starts to start the experience we'll create a function called start experience uh that locks the pointer and hides the menu locks the pointer meaning activate the controls okay and we'll also add an event listener to the play button to start this experience so function start experience okay and here we will add our logic then as we said we use this function start experience that inside will hide the menu hide the menu and here lock the pointer okay and we said that we'll also add an N listener to the play button to start this experience okay because this is the function but we want to add it to to to to the button and the button is uh okay the ID play play button is this one yeah is this one okay so create a variable for this play button play button and it is document uh this is pure JavaScript okay uh get element by ID get element by ID okay it was play button play button I think underscore yeah play button score okay okay so we have this play button bar uh variable and now let's uh use it play button that add event listener we add an event listener to it okay so when we click we will we will use this function stat experience we click this button we fire this function okay for this it's always JavaScript it's not 3js click the name of the event okay it's the name speaks for itself and the second uh argument is the function that we will fire start experience okay so on click fire this function that we will finish here the logic so we said we want to lock the pointer inside the start experience function we will add uh the lock pointer and hide the menu as we have the comments here for that for the lock of the pointer we simply uh add here controls. loock yeah simple as that simple as that and for hideen menu yeah let's create a new function make the code clearer so uh create a new function let's call it hi hide menu because we will then later also show it yeah we we'll create two function hide menu and show menu so hide menu okay created here this function hide menu to hide the menu it's always JavaScript and to show the menu the same thing hide menu function hide menu okay we will grab the menu because what what we will hide what menu this one uh okay this one with ID menu It's the whole element so const menu again we will refer to to do this document javascript. get element by ID and it was simply menu right menu yeah now that we have this uh uh variable menu we can hide it menu. style uh menu. Style do. displayed and as we said none we hide it simple as that okay so this function is used here in our start experience we also want to show it later so show menu it's pretty much the same thing show menu we can just copy this okay the only difference is not none but block okay so we have these two two functions uh we are not using the show menu yet because What's Happening Here document okay typo document where are you where are you document okay here another okay uh cannot read properties of null oh yes of course it's n okay oh because I commented out this I commented this this of course it's null because display button doesn't exist here it's null yeah simple as that yeah uh you see I click this button nothing happens but I activated the controls I press ask it stops I click but okay it's working like it's triggering the controls when I click click ask it stops but the menu is not hiding let's check okay okay guys I I saw the arrow as always I sometimes make stupid mistakes so bear with me yeah it happens very often uh I don't know why I just forgot the syntax uh the basic syntax of this we just assign to n okay and also sorry here's block and here is none but we assign To None don't pass it as a parameter okay okay just a stupid error it should work now we click HIDs okay great presses it will show again and stop we click controls are activated and the menu is hidden presses okay controls are deactivated and the menu is back okay it's done everything correctly okay I have up and down but I don't have the forward and backward movement I will add it we'll add that now and we are done I think with that feature let's Ed it here we have the key codes and we just need to to add the forward the backward uh movement uh yeah also add for w and uh D A and S keywords okay so here uh we will modify this the right uh the right arrow key 39 is for the right arrow key uh I also know that here we can add for uh the right is d right yeah is D here we can do or if key code equal 39 which in the table we showed the last the last time we showed the table that every key has this key code okay and for the keyword D is 68 so if key code equal 39 or key code uh uh equal 68 okay uh in this case we will not use translate X or Translate Y we will use uh also we will not use the camera movement here but we will use for smoother you will see we will use the controls movement okay so here uh instead of camera. translate uh X Etc remove it and add controls. move right simple as that and pass uh Z Point add more speed uh let's try eight 0.08 let's try the left okay yeah yeah you see it's better okay uh we'll do the same thing for for the others okay so also here that we have camera done translate x uh controls that move right okay but we'll also add here uh this is left so if key code equal 37 or key code sorry or key code equal 60 60 uh 65 is for for the the button a controls uh move uh move right yeah but we can add the negative here okay or move left left let's try should work also I think okay uh this doesn't work yeah this doesn't work works okay um move right but add negative here right Works left works yeah perfect okay great so use controls that move right but use the negative for negative for left and positive for right okay so up C and down so I don't want this y camera I Want U controls forward and controls backward okay for that uh we will use again the controls but first if key code equal 38 and also uh uh key code uh equal uh 80 87 yeah 87 is for for for W uh controls. move forward and here again 0.08 okay the same the the same speed you can change the speed uh As You Wish Al here also here as with move right that we changed the negative for moving left the same thing to move backward use move forward but just add negative uh negative value here okay so negative it will move backward but for the down uh which is the the S key if key code is equal uh 40 or if key code is equal 83 which is uh the S key move backward okay because we have the negative here let's test it should be correct yeah it should be correct click activate controls we move around and let's let's try to move forward okay forward works like a charm backward works like a charm left and right okay it works so for example I want to go this way you see that it's smoother nicer because I can move the mouse and yeah just by you know it's better like this okay guys that's it we we did it I will leave like this small uh challenge let's say for the beginners of course to adjust yourself the scene to add more paintings on the left and the right walls uh the movements are are okay you don't really have to do anything about it you can change you know the colors because we have this strange colors for an art gallery but if you remember I added these colors just to differentiate you know and see uh the walls and the ceiling uh in the next tutorial I will try to optimize this of course make it realistic I will try to play with the lights I will try to to optimize the chter we want to see the walls as real walls uh yeah optimize it make it look much better maybe okay if you did it yourself at the time for the paintings I mean if you are doing it yourself uh it's great uh if not I will do it so you can check if you had any issues with positioning the paintings on the wall but maybe we can add like I don't know a better way to display okay so see you in the next tutorial thank you for following me bye in the last tutorial we built the foundation of 3D art gallery setting up the walls the sailing the floors adding like a simple Cube we also implemented a basic movement controls uh Etc since then uh our gallery has had a major upgrade and this time uh I added real artwork implemented Checkers to make our Gallery look even more realistic uh yeah I'm sure you can find better texter very high definition out there so yeah feel free to find even better textures and yeah we even added a dynamic lighting system to set the mood a bit uh I will show you uh but yeah I improved some other things like movement I got feedback from someone commenting on my channel uh so now we have a better movement controls it is smoother now I fixed those things but I've also worked on user interaction and now when you approach a painting an info card will appear displaying details about the artwork okay I will show you so you see the textur on the walls now the walls and the gallery looks better as I said we can find better textures of course but I didn't want to use like very high definition textures because yeah the performance uh will be you know you see also the angles the borders uh it's they are better defined now because the Shadows are showing better and the lights so you now it really looks like a gallery you know like a r but I want to show you the the new feature that uh we have now okay you see we have an info card it will show yeah the title the description Etc when you get close to to the artwork you go away it will disappear you get close it will show if you change to another one it will show show information about the other one and it's a nice thing this is a feature that many many people requested me even writing me on private so not only on this tutorial but also in the other tutorials uh this I I saw that this was a feature that was nice to have from many of few so yeah I addit it and we will go through it how to implement it step by step and I also am commenting every single line in the code on GitHub so for those of you that are you know are not beginners uh please bear with me I know it's not the best thing to have like comments on every line but for the sake of our tutorial for the people that uh really want to learn the basics and they really want to understand every step not only like look at me I'm doing this look at me I'm doing this oh now we have this and you just code there you know there are many tutorials when the guys just code and you follow and copy paste and yeah you get the project but in the end you are not really sure if you really understood the things and the next time that you want something you will always rely on that YouTube tutorial so the secret actually is that uh those who makes tutorials they want this they don't really want you to you know to learn how to do things yourself or uh they don't really want you to to create things yourself to to to to teach you how to do it why you are doing this okay so uh like uh you create a variable why you are creating this variable how did you know that you need this variable how did you know that you need this function why this function what does it mean you know how can I know that oh I would need this function how to to to to make the the you know the problem solving how to debug things how to solve problems so this actually are the most important things to to learn for everyone not only for the beginners but yeah we know that uh many tutorials they just you know teach you how to rely always on those tutorials so you will always come back to to their channel to their tutorials and yeah copy paste and follow the video they are like spoon fitting tutorials okay this is why I will explain every step I will comment every line of code on GitHub so those who are experts please bear with me just ignore the comments you know but I think for other people uh the comments will be very very helpful even if you understand it now maybe you will get stuck and you will forget okay and you can turn back at the code and see okay this is about this this has this function this means that etc etc etc okay I hope it will be helpful if not please tell me or if you have any ideas if you have have any suggestion what you'd like to have you know what you'd like to explain more or what you would like to just stop it amilon just stop with this blah blah blah and just go and code okay uh I also changed a bit the menu you have you you see there are some slow animations um yeah the fonts and everything yeah the pencil the the mouse now the pointer is this pencil and there is this transition when you go back this slow animation you see it's nicer of course we can do even better with the Styles and I'm sure many of you are more know knowledgeable in CSS than me you are better than me in styling I'm sure many of you I'm sure they are so if you can do better yeah please do it if you want also to share just Fork uh the GitHub repository and yeah send a pool request if you have something very nice or cool that you think would be nice to share with other people's if the design is better than mine and yeah I know there there are guys that are doing better with the design than I did uh okay what else I I in the future I have some ideas with this tutorial yeah I would like to to to to continue this this project we can do I think very cool things with this project it can really expand so I think we would love to explore more advanced features okay we can move on with more advanced stuff I think for example imagine an audio guide providing you details about each artwork as you approach them okay artwork or your designs or your links to project you know you want to showcase your project or your own portfolio it will be your personal portfolio to show to recruiters in very nice way it would be like very nice if you have a personal portfolio like that and I'm sure recruiters would love it to see it and yeah why not if someone uh is looking for a new job it will help but yeah imagine that uh we had this audio guide you move uh through the gallery you approach this projects and artworks and an audio will start playing explaining you know the project or the artwork in this case explaining van Go's art I think it would be very nice or you can add for example your voice your audio recording explaining your project this is my project I work with this company I did this and I did that and that's it now let's start with our tutorial and let's create this new features oh I forgot the most important things and yes that is the most important thing I refactored the whole code so we had the previous uh project we had like one file MJS file now I restructured and refactored the whole code it is cleaner better it is modular it has the best practices and yeah we have a file for every functionality lights walls the colliding system oh I didn't show you we will also add the colliding system you see now we cannot go through the walls you see there are some Physics like I want to use the physics engine but I thought it would be too much only for the colliding system so I used a very simple trick to do this colliding okay because there were some options do it with a physics engine like ammo JS or Canon JS do it with Ray casting also but I found an even easier solution so why do something complex when you really can do it in an easy way of course we will explore the physics I don't know if we can add like I don't know features that involves physics for this project but yeah maybe we can do it in in the future okay yeah let's start thank you for being here and please follow this tutorial okay so I want to show you the changes and the first thing that I want to show is uh some fixes for example fixing the movement someone reported that they were having problems like they had this lagging experience uh it was not smooth when they move and this is because uh this issue uh that uh someone described in the comments is because the movement isn't in sync with the frame updates every computer has different frame updates because depending on the computer how powerful etc etc so this is the issue and that's why sometimes we use uh a Delta time for this and I will show you I fixed it in this way so this is the function that is responsible for the movement and uh yeah we were like uh checking uh now it's uh the code is changed I will show you but yeah we were checking the inputs from the users what key they were pressing and based on that code number we updated and you know we moved left or right Etc now what I added here what I changed uh it seems that that movement uh is only being processed once for each key press so this is because the key down event listener is only called once per key press so the key down this one event listeners that we had previously is uh is only called once per ke press to continuously update the movement while the key is pressed okay we should separate events for key down and key up and maintain a state for the key is when being pressed okay don't be confused please because I will explain and for that okay we will use an object to track the state of the Pressed keys I created this object to hold the key pressed so Arrow up arrow down arrow left Arrow right and yeah you know w a s d so this object uh is to track the state of the Pressed keys so we will use this object here after creating uh this object what happens uh in this code that we have you see we have an event listener for key down okay and an event listener for key up we have two uh these event listeners are used to update the key press object this one we will update this key pressed object with this event listeners uh the update movement then the update movement function will be called on every frame so our function that is responsible to to handle the movement will be updated on each frame and we will use this Delta I will explain in a second okay but we will call this function in our render function so to call it on every frame which checks the state of these keys in the key pressed checks the states of these keys and moves the camera accordingly okay so this should provide a smoother and continuous movement as long as the keys are are pressed okay so I will explain we have this object to hold the keys pressed then we create this event listener key down this is when we press the keys so event listener key down key down is an event that fires when a key is pressed we pass the parameter event from and if event. key in key pressed check if the key pressed is in the key pressed object so the key we pressed the user pressed check if that key that the user pressed is in here on this object Arrow up arrow down Etc so if the user presses for example narrow down check uh if it is if this uh key pressed by the user it is on this object set the value to true if the user for example press the error right from false it will turn to True set the value to True okay if not if the key that you know the user pressed like he pressed like and I don't know another letter or doesn't matter set it to fults Like It Is by default the same for the other event listener key up in this case so event listener for when we release the key so key up is an event that fires when the key is released pass in the event parameter uh check if the same thing check if the key released this time not the key pressed but check if the key released is in this key press object this is to make you know continuously this updates not only with key down check if this is there if it is not if it is set the value to to true if it is not sell the value to false okay so if what the user is releasing is here set to true if not set to false okay now for the Delta time okay because we we discussed the Delta time one solution is to use this Delta Time by using Delta time we can Ure that the movement speed is consistent regardless of the frame rate it doesn't matter if my computer has another frame rate another computer has another frame rate so it if we have like another calculation uh I will see it differently another computer will be different because we have different frame rates so Delta time has this function by using Delta time we can ensure that this movement is consistent regardless of the frame rates and regardless of what kind kind of computer you have okay so uh there are several ways to to handle this but the easiest one and you know is using this clock from from from 3js it's a built-in okay this creates a clock to keep track of the of the time between frames between these frames so the clock keeps tracks of this time time between frames and so here in our update movement that we updated the code we create this move speed equal to five five per Delta time so move speed is the distance the camera will move in 1 second we multiply by Delta to make the movement frame rate independent you know independent from the frame rates this means that the movement will be the same regardless of the frame rate as I mentioned and this is important because uh if the frame rate is low the movement will be slow and if the frame rate is high the movement will be very fast so this is not what we want we don't want different performance in different computers we want the movement to be at the same regardless of the frame rate we want that speed we don't want like the car to move 300 kilometers per hour and in in another computer move like just slowly very slowly and then we create this variable previous position the previous position equal to camera. position. clone what is this clone the camera position before the movement so before the movement we clone the position before that Movement we clone it so this is the variable previous position we want this then we check if key pressed that error right key pressed is the object do Arrow right is this key here this property so key press. Arrow right key press. Arrow up key press. W Etc we access you know the keys inside this object if key press this error right or key press dot d it's the same because we will use error right or the letter D to move right uh controls. move right and we pass the parameter move speed okay so controls that uh we have we are using controls from here the uh okay controls it's the pointer locks that we did in the last tutorial so okay if we press uh error right or D controls. move right and we pass the move speed we want to move with that speed which is five multiplied by Delta time and the same if left or a or if Arrow up or W etc etc we move accordingly and here we will check for the Collision because uh as I said uh I added the Collision so I'm I will collide with the walls and I cannot go through break them through to the other side so I will stay in the room as you know uh as in a real Gallery we cannot pass through walls like a ghost but I will explain in a bit this check Collision but I wanted to explain this movement first so I hope you are clear with it and this update function in the end after creating the CL clock that keeps track of time between frame rates after creating the variable move speed to move at this speit multiplying by Delta time we call it in the render function you know the render function is the method that you know this will be called uh again and again and again and again these are also the animation so this is a loop and so yeah with this we are sure that we will call on on on every frame okay I hope you are clear with this I hope uh who commented about this issue and now it's fixed and I will explain now uh the Collision that I added how we did uh the Collision system it could have been very comp complex actually if we use like physics for that like ammo JS or Canon JS but yeah we could have used R casting also I choose to to use the simplest way for this because yeah why not why not so check Collision okay this I will show you in the browser in a second how it works I go back okay I cannot move anymore I go right to the wall I cannot move anymore sometimes you may find that I cannot move like you know here because maybe we are very at the limit and maybe the painting or something it's it's blocking us because yeah it recognizes as a bounding box so just move and try it yourself but yeah it works so how we did this check Collision okay here I created uh this function check collision and in this function uh we will check if the player the user will intersect with this walls or this solid things that we might have but in this case we only have walls no other obstacles and uh I create inside this function check Collision I create this variable player bounding box okay this is created with uh creating a new instance of box three so new 3. boox 3 and what is this this is to create a bounding box for the player so we have the player which is the camera we create like a bounding box for this to have it with us so that bounding box will serve as you know to find the intersection then I create a variable camer World position that it's an instance from just a Vector three this creates a vector to hold the camera position then this camera we access get World position to get the camera position and and store it in this Vector okay so we get the the camera position of this uh the camera represents the player position in this case Okay because the camera position is the player we move we with a c you know then from this player bounding box which is the Box three which is bounding box we just created I access this set from Center and size what is this and I passes parameters the camera position in the world and this vector with these coordinates so this uh set from Center and size is a method that checkes the center and size of this box okay and we set the players bounding box size and Center it in the camera position okay so basically it's just to to uh takes this and Center it and uh size it uh of the box and uh put it in the Camera World position we pass it here the parameter so it will Center on this camera position then I create uh a loop why I create this Loop for the walls we have the Wall Group we uh did this in the last tutorial that we created the walls we created a group of walls and now we look through it you know what the loop is right so w group. children because the group in three JS has the children inside so World group. children. length i++ so look through this uh children inside the wall the single wall is wall group. children I the element that is looping through iterating so is you know to get the wall the single wall is the the eye that is iterating because I is zero then I is one lies to it iterates on each wall on each children inside this group of 3jm and uh if player bounding box with this method intercepts box we pass the wall that bounding box so each wall has this bounding box okay check if the player bounding box intersects with any of the wall bounding boxes okay so if our bounding box the player intersects with this walls left front back you know all the walls bounding boxes because we have a bounding box also the wall have bounding box if it intersects return it true if not return it false so this is the function check Collision to check if the player's bounding box intersects with the bounding box of the walls around us I hope it's clear that's why I commanded every step and okay so this function where I call it I created this function to check and where I call it I call it in this update movement function where we move okay the user press keys it checks this object here if it's here return it to true so it means that we press one of those keys that is in the object we turn it to true and then if we then Al return to true we move it right with the speed that we defined here five multiply by data time okay so here in this update movement we pass this uh function check collision and here inside we have camera. position. copy and pass previous position if you remember previous position is the position of the camera before the movement so without getting confused after the movement is applied we press a key we move left or right or forward or backward after the movement is applied we check for collisions we move check for collisions do we have anything no continue moving move again move again with the speed of five multiplied by Delta time okay so we check for collision by calling this function here in the update move and check Collision move and check Collision if the Collision is detected at some points we will revert the camera to the previous position okay that is why we needed this variable here previous position and the previous position is karma. position. clone so the previous position we cloned the previous position where we were so we are here okay we are here this will be the previous position when we move so when we move that was the previous position okay I'm here I move one unit one matter forward I move one matter forward we check for collision with the function check Collision am I colliding with the wall I am not continue moving another meter forward check for Collision do I have any wall in front of me yes I have okay the check Collision finds that I'm intersecting with with with the wall what happens in the case if I find this checkol and returns that I am uh colliding return me to the previous position that we get it with this clone method okay so and that's it this resets the camer position which is the player to the previous position if I am intersecting with the wall okay and that's it uh if you just maybe might sign bit confusing I don't know maybe is just easy as it as it is but if you find a bit confusing just you know go back again just two times and I'm sure you will you will have no problems so this is for now for uh the movement update that is fixed and for the Collision this was the changes that I made for this what else I also added the checkers as you can see as you can see the checkers has like these Checkers wall texter like it's more realistic that the white material the simple material I found on internet you know here here on public you can check yourself I just put there some some textures that I found you can experiment and you know try all of this if you like another texter use whatever you want or I'm sure you can find better Checkers for the walls on internet on Google on Bing I use Bing now I don't use Google anymore but whatever uh you can use whatever you prefer and it's here let's find uh World texter if I'm not yeah World texter look at the comments that I edit okay uh yeah I will edit the at least the first time maybe we will delete it later to clean it but I will leave it because I know what it will be useful helpful for for someone so I changed here where we have the text loader. load that we explained the last time that it's the loader for the Checker uh I add this uh IMG white texture jpeg you can use you can try the others but I found this the best one from this one you know I didn't very you know deep research so you can find better texter you find it just please tell me on GitHub we can maybe change it free texter of course because yeah we we care about copyrights uh yeah you know this the world texter uh rap s equal to this repeat wrapping what is this confusing uh variable and I added the comment here W S and W T are properties of a texter that Define how the texter should be repeated in the X like left and right or you know in the y direction so we have a Tex first how we want to repeat this you know in the x axis or in the Y AIS uh these directions uh RS is the horizontal Direction the uh the X and r t is the vertical Direction the Y and this repeat wrapping that we get from three is one of the available wrapping modes and it's like you know it's the default usually wrapping mode for for chter okay so this means that the texes will be repeated in this specified Direction in this case w s which is the horizontal and again w t in you know the vertical the Y and this W texor repeat. set it sets you know to repeat uh property which is a vector two that defines how many times the texter should be repeated in this horizontal and vertical oh sorry uh directions and if we yeah if we choose uh one this means that the text will will not be repeated it will only be displayed once on the material etc etc okay so I changed also the texter here so that is for the wall texter but I want to show also something else uh another comment asked me how to rotate the paintings I'll show you here uh they have a problem they had a problem with the positioning this right and left wall paintings okay like position it uh the correct way because I suppose and they confirmed to me that they had this problem that the paintings were showing in front of us not you know so they wanted to know how to rotate these paintings that they adapt to the left and right walls I'll show you so where are our paintings yeah you see this code it's be it's becoming a bit hard to read I know you thought about it and that's why that's why I refactored the whole code and now we have like every functionality has a separate file you will see and uh I really uh advise you to follow that part a bit later I will do it later uh it took me some hours actually to to make that refactor uh but I advise you to follow because that is very important maybe one of the most important things in you know when you have a big project you need to follow this uh you know patterns and uh best practices uh make the code cleaner and modular and readable maintainable etc etc so yeah I advise you to to to check that that part later so we were in the paintings right so we want the painting where is the painting create painting here we are so in the last tutorial we had only two paintings so painting one and painting two that we pass here as a parameter to this function create painting which is here we have the image URL the width height and the position as parameters to create every chel here we created the texture the material the geometry and the mesh so basically we create this plane geometry for the paintings and every time we want to create a new painting we call this function create painting So painting one equal to create painting and we pass this parameters here custom parameters as we wish so I pass this zero J back the width 10 five height and this Vector three for the coordinates in X X Y and Z for the painting two the same thing uh now for the painting three and painting four for the left and the uh for the right and the left walls that was this issue of this plane in front of us instead of adapting to to to the wall so what I did here to fix that uh small issue so painting through here the same thing we pass the image URL we pass the width we pass the height the coordinates for the vector three X Y and Z and here uh to fix it we rotate this painting and in this case so painting three rotation. y we rotate on the y axis math. Pi ided by 2 and we mentioned math. Pi in previous tutorials if you remember but if you don't remember math. Pi is 180 Dees okay so this is degrees in radians so math that Pi is 180° is half half the circle okay so math. Pi / 2 is 19° so I left the comment is if we don't rotate this it will show up in the front of us instead of line correctly on the wall okay this is the small fix small trick uh the same for painting four but the only thing the difference is that it's negative here okay so the same as above but negative just negative for for the other wall and yeah I also add added the the walls for the walls the paintings for the back wall so Al no I added two in the right wall two in the left wall and two at the back wall and that's why we have in total eight eight uh paintings and here you will see the same thing for the painting I8 which is the painting in the back wall I rotated it 180 degrees in the y axis because if I don't do that we cannot see the paintings from behind it like we if we if we see it here like we have the painting of the back wall so this is the palm of my hand is the painting if I am here I can see the painting but if I am here I cannot see anything I will not see it will be the texture will be visible only from if we have it in front of us okay so if I have the the painting here I will rotate it 180° to be able to see it okay this you could have run in this small bug if you did it yourself so yeah this is and these are some of the changes uh for the menu that you see a small animation and other things I'm not going to make the tutorial for that for CSS because we are not here you know to make a tutorial for about CSS but for 3js and 3D programming so but you will find this uh Styles in the CSS file here copy everything if you want to check how I did it Etc you can check you can check uh here because I dided some you know I added some key frames for the animations so it's interesting maybe for for someone so check here and copy it's in the GitHub or something else I had like a comment I uh on my GitHub uh someone opened an issue in the repository on GitHub because they were were having a problem with a project so the problem was that they were trying to make the project go live by you know clicking this go live here or you know usually how you do with HTML uh open on live server you know on HTML they open on live open with live server so open with live server but this doesn't work like that uh in the last last tutorial I think I didn't mention this so sorry if I didn't mention I think I did I don't remember but yeah to run the the project every time when you are on the GitHub repository click the button the green button there which is uh can I find just a second just a second let me do I have it here I'll show you I updated also the RM file so you have it everything explained here okay so we have everything explained here of course the first thing first uh you need uh okay download it here you see this green button code you can clone it with Git clone and pass this URL here so create a folder open the terminal and G clone URL or just download zip and open with visual Visual Studio okay I remember someone like corrected me like for the wrong spelling because I say visual but yeah Visual Studio whatever and uh G clone or download zip after you have this project on your computer of course you need no JS you should know this but yeah if you don't know you need no JS environment because JavaScript will run on the browsers supported by you know the browsers but locally we need nodejs to have the environment to be able to run JavaScript because not JS it's not a programming language okay uh of course you need Visual Studio here are the links to download and then after cloning or download the zip here clone or download you in the root in the root folder just run mpmi or mpm in it will install the not modules all the dependencies this big guy here this not modules that has like you know it's heavy as a black hole so it will install this I think because we as we said I mentioned we never never post this on GitHub they are too heavy uh after installing the dependencies we run CD SRC here okay stop the server okay from the beginning as let's say I'm from the beginning I have the git bar so I usually do p WD to to check the path but uh you can do uh CD if you don't use G bash but you use Powershell you use CD it will show the path I do PWD to check the path and I am on SRC folder okay I did CD uh dot dot to go back One Directory so now I am you know at the this 3D art gallery the root folder here you do mpm install or mpm I after installing the not modules you run CD SRC with CD SRC you go inside this SRC folder here because it's here that you should run the next command to run the project live look I'm here now on SRC you see and here just npx Vite run Vite which is the build tool we use to run our project locally okay our local server MPX V that's in just a second less than a second you will see this address here local or press h for help but just click here and you have the project live okay if you need help for you know press h r to restart the server uh you to show server URL o to opening browser C to clear the console yeah you clear everything and uh yeah and Q to to quit just to quit okay it stopped so you need to run it again if you stop V is very nice V is very nice now I only use V I don't want to see anymore create react up for example for those of you who use cact up I think is is going to die and I think it's is dying no I don't know if anybody uses anymore um I think neither is his creator likes it anymore but yeah V is very very cool it's the creator of Vue vuejs that uh created and I love VI by the way lately I'm not using react but I'm using view for my work and also whatever so this is the problem that someone opened an issue on GitHub for this so keep in mind node.js you need the editor of course after installing nodejs and nodejs is pretty straightforward to just download install it will do automatically uh open on vs code and you know follow these steps that we just uh mentioned okay for now is this uh The Next Step will be to to refect Factor this whole code okay and we will create file for every functionality okay it will have uh it's not so simple because yeah it's a mass with a big uh very long code and so I advise you to follow this part too okay I will do it in a second Maybe I will go and you know drink a glass of of water because yeah I'm talking too much okay now I will show you how to create the info card so the feature here that we get close to the artworks and we show the information so it's a nice feature to have not only for this project but also for other projects that you might create in the future so it would be good to to to learn it let's get back to our code and here as you can see there is a lot of changes because as I said I I refactored all the code and now we have this structured folders you see for every functionality we have a separate file and it's very clean now you see now this is our main JS it was like 500 600 uh lines of code before I refactored and now is just you know some line of codes and everything is uh cleaner I will explain this later but for now I just want to to to show you how I did the info card and then I will I will show you more in detail about the refactoring okay so for the info card I created a separate file because okay after refactoring the code I created everything like you see bounding box saling event listeners floor lighting menu movement painting data painting GI paintings rendering scene etc etc etc so for the info card is this component here this module painting info okay and uh here in painting gifo I create two two functions display painting info and hide painting info one function is to display and one one is responsible to to hide the card so this function first of all we create a variable info element and this variable is just to you know to get the reference to to the Dom to this element with ID painting info which is this one here in the in the HTML so this ID here we get a reference to this because inside here we want to create you know that element to show or hide so after creating this info element uh we set the content inside and to create the content inside this is Javascript it's nothing to do with 3js is vanilia Javascript vanilia van you know JavaScript plain JavaScript uh to create content inside we use inner HTML so info element. inner HTML equal to first we create a title and this title is from info. title and this info is an argument passed here I will explain that where we get it from so info. title uh info. artist info. description and the year okay so we have this element here and to display we use this class list. add and the class show this is to show to to add the the the class show here so to this element here we had the class show because we want to point to that later the same thing with this function hide painting info we create this info element to get the reference to that ID painting info and then we just remove the class show so here we have this class show and here we remove this class show and that's it two functions hide and display then when when we will use this and where here in the rendering as you can see now this rendering is now extracted here in a separate file but this was you remember in the last part of MJS there was the function render which is you know uh the animate uh function to Loop and render the scene and do the other stuff that will okay render on every frame because yeah in this render we call this request animation frame which calls the random function again so it runs over and over and over so this is the function to render things but yeah I refactored so it's not in MJS it's everything here so I import three here I import this displayed painting info and height P painting info from painting info JS this one that we were exploring together to export this functions from one module to another module again this is Javascript uh you add this export at the at the start okay so export function display function etc etc you can also make it an nrow function like export con display info equal okay so now now this is an nrow function yeah we can make it like that even here export const hide painting info equal error function okay as you prefer it's the same thing just you know this is more modern real function okay so to export functions you add this export here at the beginning and then uh if you there is also export default usually when you have only one uh component that you want to use you do the export default Etc but here export con is just when you have in one file different functions that you want to export this is another topic but yeah in basically you just add this export and you can export it in another file so here Import in this case you need to add the brackets here if you export it like this if if it was export default it will be without brackets again this is a another topic you can uh research more about this ways to you know to export modules in 3js U sorry in JavaScript because this is plain JavaScript but yeah we export these two functions okay to use it here and in this uh uh render function okay you remember again this is function we can again convert it into an nrow function it's not a problem it's the same thing uh in this render function which calls itself in a recursive it's a recursive call with this request animation frame again and again here what we do after we pass this update movement you remember the function update movement which was in main JS but again I will explain all this later but for now just focus on this uh feature to display the info card so we call this update info here in the render function uh we create first of all we create a distance three sh equal to eight it's like eight units or eight meters in this case Okay so this distance three sh is the distance that will be from us the user the player and the the painting the artwork as you prefer saying painting or artwork so it's the distance why we want this distance we want because at a certain distance we want to display or hide that painting so we need a variable to to store the distance then we create this let because it will you know it will not be a constant it will change we will use it you know this conl in JavaScript no need for for that so we create this painting to show what is this this is the varable which is responsible uh to store a value in which we want to show the painting or we want to not show show the painting uh explaining it a bit in detail I will show you the code here we have these paintings okay don't worry much about how we get now these paintings in this new refractor code but these paintings you know we get it as an argument uh we passed it here for this setup rendering I will explain it later but for now we Loop through this paintings okay paintings that for each and uh then we create a distance to painting and to get the distance to this painting from the camera to the painting because the player remember the player is the camera so we are the camera that we move as you know the player the player the the user so to get the distance from us to the painting we use camera which we are the user that position and we use this method here distance two and distance two we pass a parameter which is the object that we want to get the distance two and the object is the painting we want the distance to the painting so the parameter will be this painting. position get distance from the painting okay and we store it in this variable distance to painting simple as that now we create an N statement to check if distance to painting this one we get the distance that can be be one 2 three depending how far it is if this distance is less this than distance three should this variable here which is eight so if the distance from us and the painting is less than eight okay then the painting will be showed so the painting will be stored in this variable painting to show that's why we created it okay like a way to you know to know so set painting to show to to our painting okay in this case the painting will show we we have that value and then how we will use this logic here that we set the painting to painting to show if painting to show like if this is true okay so if there is a painting there to show because if this is true so it means that uh we are less than 8 m from the painting So if this is true and we are less than 8 mters call this function display painting info which is this function here that we imported from this file which creates this H uh HTML elements okay so if painting to show is true call this function and pass inside painting to show. user data. info and this is an object from painting data okay so painting to show user data doino because this user data here we will get it from the painting so each painting you know so we'll have a user data and an info I will explain this on how I refactor the code but yeah at the moment you just need to know this display painting info and pass you know the info of that painting or else if this painting to show is not true hide the painting info so do not show okay and that's it this is we have this HTML here HTML element and we have the styles for this painting info I added the Styles you know some transition I add it at the top etc etc you can find these styles on GitHub okay and that's it this way we can display the info card okay for each painting the painting changes and the info card of course changes that that's it okay guys now I will explain um the refactored code so as you can see I have many files now and the MJS is cleaner so let's see these are the Imports okay so first of all we import everything from three as usually then we import scene and setup scene from CJs okay and then CJs here okay then we EXT uh uh get this these variables from the setup scene let's take a look at this uh scene and it is on this files scene scene okay here okay so I extracted all the logic and the code for the scene in a separate file okay so basically we import uh everything as three then we import the pointer locks we create this uh scene here as usually create a new instance of three sin this is the same code but with a difference that we have a function we create a function for that code that we had on Main js on MJS we had like the camera the render controls and everything the same thing okay but we create a function that we can export this is the difference okay so get that code and create a function which can be export okay and that's it so I added some detailed comments you can read and I think they will be useful if you forget something for example you can see the code and check the comments okay so you create the function and you can export it in other modules okay so here there is pretty much the same code that we had on on MJS it's just that we export it now here I don't know if I changed anything here but yeah the main thing is that we declare this variables camera controls and renderer and I return them here I return the camera controls and render so that we can use them in the other modules so this function returns this camera controls and renderer so we can use it in the other modules okay so we get the scene here uh okay as you can see now we can get this uh camera controls and render here that we were returning from setup scene function okay this is just a simple texter loader to load the texter and we need it here because we are using it here as a as an argument so then we have the walls we also extracted the code for the wallts in this create walls function which is imported from Walts do. JS as you can see let's take a look so wjs the same thing we need the three here because okay and we create a function which can be exported the same thing so this fun function takes two parameters scene and texture loader because yeah we need scene when we add things see that add for example and the texter loader because yeah we need the Checker loader to create the checkers and yeah this is there are also comments everywhere here and uh yeah as you can see this function Returns the Wall Group so the wall group is the group that has all the walls front back left and right so this function will return this wall group and we can use it in the other modules as we are using it here to render the walls in the scene because the main JS is the primary let's say file to render everything the main JS has modules that we need to render all the same okay so for the walls we have it here we create this variable even though we it's yeah we use it here but we create this variable and call this create walls which takes the scene and checks the loader so this is uh the beauty of functional programming because if you see here this gr walls takes two parameters okay scene and text to loader so how we get this scene because I don't have the scene here I don't have the scene here so we get it when we call it here when we call it here we also pass it here so SE here I get it from this scene from scjs so I import the scene from sjs here on MJS I pass it here as a an argument and then in the wals JS I can use this here can see I use it in this cind just to add this whole group basically I needed yeah just to add this but I don't have this scene here so I need to to to get it from Main JS which is also uh taken from this uh you know CJs okay and that's is that's it for the walls the same thing for the floor we import this function setup floor for floor JS and and it's uh Flor JS okay Flor JS the same thing import three because we will use it create this uh function that we can export and again the scene is passed in MJS where this setup floor is called so we don't have the scene here use it but in MJS when we call this function setup floor we pass the scene from yeah the CJs okay you see the beauty of functional programming it's the code is cleaner of course and yeah uh for the texter loader uh I just create a new from three because I can create it from three or I could pass it you know but I create a new tter loader and yeah the same thing and this does it return now this just adds the floor to the scene that's why I needed this just adds the floor to the scene and when we will call it here on MJS it will render the floor the same thing for the sailing you see how clean it is like this way and we can control and we can maintain the project better we can read it better if someone else uh wants to work with this project they can read it it's more readable and it's uh more maintainable and also for where are we okay sailing for we explained the lighting okay let's yeah let's start with yeah with paintings or lightings because yeah painting is a bit more complex so lighting we create this function set up lighting which takes scene and paintings as parameters that yeah we will pass it here on Main JS always this is the logic paintings we get it from create paintings from painting JS and we pass it here we create the ambient light and the spotlight we did this in the old tutorials we set up this settings for the spotlights and we return the spotlight here to create the spotlight uh we use this Spotlight and create like one two three and four with this coordinates okay and we add it to the scene the spotlight and also the other spotlights and that's why we needed the scene here and that is for the lighting then we have paintings we use this create paintings from paintings JS find it here so to create this uh you know we extracted that code for paintings that we had the function create paintings also in main JS and now we will use also the painting data which is another separated file painting data which has the data for you know know all the paintings we have info object here etc etc the image SRC width and height so this array. from if you don't know creates an array from an array like object the first parameter is the array like object the second parameter is a map function uh this creates like uh an array of four because we we we will render like uh four paintings for a wall four four four and four at the back the map function chases two parameters one is the element and one is the index the map function Returns the value that will be added to the new array okay so this map will return the value that will will be added to to the new array in this case we are returning an object with a painting data so we have the painting data here uh this is just a placeholder for the element we are not using and we yeah we don't need it at the moment and I is the index and we use it to set the painting number and since you know we had like plus one because uh yeah the index starts at zero as you know for the arrays so 0 + one but just don't get confused of this you can take a look yourself find it on GitHub so yeah it's just you know we can we can change this actually I will change it because I I will let like description for each each artwork so I will change this I just wanted to make it quickly you know four paintings for each wall just to set the position but we will change this all don't mind too much but this is the idea we import this painting data for from this painting data JS we create this function create paintings which takes scene and textor loader that again uh this arguments will be passed from Main JS where this create paintings is called here create paintings is called we pass scene and text the loader we create first of all a variable which stores an empty array this will be the array of paintings then we Loop through the painting data that we get from this file that we we already seen then we create a mesch for each painting like we create you know a 3D object for each painting and the 3D object is a mesh and the mesh is a combination of geometry and material as you already know by now then we set the position of the painting and the rotation of the painting then we add a user data property to the painting that will hold the painting info okay information so painting that user data we create this type of painting we just need this uh so we can check if the object is a painting or not so it's a type of painting and the info we add data. info we add the painting info to this user data object and data is the current painting object in the for Loop okay is the is the painting object we are iterating in this uh loop and info is a property of the painting object that holds the painting information and we saw that we have we have the information here for for each painting yeah then painting uh that cast Shadow true to set the painting to cast The Shadow and receive Shadow to set the painting to receive the shadow then in the end we push the painting to this array of paintings okay so we have the paintings there and we return this paintings okay we return this array of paintings so we have the paintings in this array that we can use later so here here we call this create paintings we create this variable paintings which calls you know it's assigned to this function and we can use them later the paintings which is needed here in the Bing box that we will check and also in setup rendering that we will check to is used here as a parameter you see like uh how nice it like this way it's different but it's way cleaner and also maintainable and yeah the lighting we have the bounding boxes we have the setup plate bottom oh yeah let's check the bounding boxes which which checks the walls and the paintings you see is to create the bounding boxes for the walls and also for the paintings uh we need this because we use the Collision you remember so for the Collision we used these bounding boxes that we checked if they intersects with with a player bounding box okay so we have this file here bounding box yeah we import three from three then we we create this create bounding boxes function which chees these objects and what is happening here we have also this condition if array that is array this like uh the contrary that it's like it it turns from True to false so if it's not uh an array and in this case we we check if the object if the object is an array or not if it's not we will assume that this is a 3js group it's not an array in that case if it's a 3js group if this is not an array we set objects to objects. children because we assume this is a 3js group and I will explain it more in detail here because in 3js a three group is a type of object used to create like you know parent child relationship between objects so there is a parent and then there are you know the children and uh yeah in this uh group in other words a group is an object that can contain other object in inside that's it and we we want sometimes this group because we can manipulate several objects at a time as one okay so the children property uh of the group of three group is the n array that contains all the objects okay so the child objects inside that are part of of of this group so when we add an object to a group uh with group. ADD as we added the walls wall group. add front wall uh back wall left wall and right wall we can access that object with group. children so we can access them uh when we need so in our code the create walls returns a group for the walls you remember we have the function create walls it it returns a group that contains several wall objects and when we pass this group to this create bounding boxes because this create bounding boxes will be used to create bounding boxes for the walls and for the paintings but the walls are three group the paintings are an array so this function here to check the objects parameter an array and also a three group grp we did it like this with this conditional okay I hope it's clear but yeah uh we when we pass this uh objects here to this function create bounding box uh we want to create a bounding box for each wall in the three group and to do that for the walls that are group we need to Loop over all the children all the children array of this group so when we call create bounding box walls here create bounding box walls the object's parameter of this function is a group objects so for the walls when we call it it's a group object and yeah we need to in order to to Loop over this wall in the group we need to set objects to objects. Children okay I I know it may sign a bit confusing but basically we are using this uh create bounding boxes for the walls which are group and for the paintings which are an array if they are group we need to to set this to the objects we need to set to objects. Children which is then the array of of objects wall objects uh so this was when uh this object objects were a group like the walls what what about when they are an array as for the paintings in that case like uh create paintings that we had in paintings paintings are an array here as you can see and in that case uh since create paintings returns an array and not three group The object's parameter this one objects is in Array so we don't need to do anything in that case as I explain in the comments uh below so for that reason that's why we start this function by checking if it's not an array if object is not an ARR assumes that it's a group and sets objects to objects uh if object is already an array it skips this this step so if it is an array and not a group it will skip this step and in that case we Loop through objects which is an array and we set you know a bounding box for each object then object. bounding box set from object which set the bounding box to that object which is you know the object iterated each object yeah maybe I didn't explain very well this part but yeah you can read the comments and I'm sure you will get it because yeah I commented this whole thing here and you will get it this is just because we are using the create bounding boxes here function to pass the walls and to pass the paintings and they are different one is a group a three group and one is an array and we need this check uh we have this add objects to scene which takes scene and paintings what is that we have this in scene helper JS is this just this piece of code here this function will take the scene and an array of objects which can be passed dynamically uh we choose and add each object to the scene so it will uh loop objects that for each at each object okay so this is just function an helper function to add each object to the scene why we need this we need it for the paintings as you can see we call this paintings here with create paintings we created the paintings we return the paintings the paintings array we return this paintings okay we created and we returns this paintings but we need to everything should be added to the scene as you know by now and with this helper function add objects to the scene we can add this paintings okay and that's it then we have setup play button you see that in on Main JS pretty much we see everything that we have so we see what we have here it's very readable even for someone else that just opened our project and they want to take a look and understand the code they see here on MJS everything and yeah they can understand and redirect it to this functions and modules so we have set to PL button and the file here set up plate button is from menu JS and this is for the menu to show or hide the menu okay ask show and hide the menu that's it okay so we had this hide menu and show menu you already know this functions because you had it on Main JS I just extracted the logic with just uh added this export to export it also the start experience you already know also for the play button which just gets a reference to this play button in HTML with ID play button this one then adds a click event listener to the play button to start you know the experience and that's it we have also the menual logic here separated uh this play button as we saw is uh exported to main JS and it we pass the controls to it here because we don't have the controls you see the functional programming we don't have the controls on this file on this module so we call this function here and we pass it from you know from here from njs because we get it here we get it from setup scene okay so we import the setup scene from scjs importing the setup scene we the structure this uh variables for camera controls and renderer that we get from setup C and then we pass it we pass this controls also here on setup play button and then we use it here on menu JS that's it the logic what else we have we have setup event listeners that again it takes controls as a parameter set up event listeners okay here and this is the logic and the code for the functions on key down and on key up the object uh key pressed that remember we we created in the last tutorial is from this movement uh file which is a separate uh file movement here uh we have this key press which is uh okay exports const key press so we can export this and we import it here from Movement we also import this show menu from menu JS that we already saw and we add uh the controls parameter which is the pointer lock controls and this path on Main JS here setup event listener we pass controls that we get from setup scene okay the same logic you see the beauty of functional programming and then we add the the event listeners uh to the document which is the whole page so we have key down uh we have key up and unlock okay so key down is the uh the event when the key is pressed okay key up is when the key is released and yeah unlock is when the pointer is unlocked so here we we add an event listen to the controls to show the menu when the pointer is locked show the menu okay we already did this part for these functions uh the event is the object that has the key property so ev. key in key pressed check if the key pressed by the user is in this key pressed object if yes we will set the value to to true so if the user presses Arrow up we will set this false to true if the user presses error right we will set this to true and so on okay if the user if you know the key that the user presses is is is not we will set it to fals as it is by default when the key is released for the on key up so the same as for key down we set to false when the key is released so if the key is in this key press object we set it to false when the key is released so the user releases the key we set it to false if it's already true okay this is for the event listeners we have this movement uh yeah that we we did in this tutorial that we fixed and updated for smoother experience so yeah I added some comments here details comments so you can read for everything but yeah just to make a recap we have this update movement always exported it takes Delta controls camera and walls okay uh we get these parameters from setup rendering where this function update movement is called and if you see here in rendering doj we have this function setup rendering okay you see these parameters okay so we take them from this setup rendering and setup rendering gets the parameters from Main JS this setup rendering gets these parameters from MJS because it's here setup rendering because yeah we get it from setup here because a bit movement is called here in the yeah in this rendering JS okay you see it takes this parameters here when where we call it parameters we get from setup rendering above from this which gets from MJS as we as we said this move speed is five multipli by by Delta time move speed is the distance the camera will move in one second we multiply by Delta Delta to make the movement frame rate independent or you know the frame rates this means that the movement will be the same regardless of of uh the frame rate that each computer might be different and this is important because the frame rate is low the movement will be slow and if the frame rate is high the movement will be fast this is not what we want we want the movement to to be the same regardless of the frame rate okay we have this previous position which is equal to camera. position. clone we clone the camera position and store it in this previous position okay because we will use this to rest the camera when we check the Collision so this previous position is the position before uh before we we we move so if we collide with the wall we will reset this position to the previous position so check the the keys that the user is is is press this code is self explanatory if we press error right or D move right and we pass the speed of this speed and then we check for the Collision after the movement is applied we check for collision by calling this function check Collision which checks these parameters of camera and walls and if a collision is detected we rever the Karma's position to its previous position okay so it cannot move through through the wall preventing the player yeah to to go through uh yeah if check Collision uh ca. position. copy previous position someone might ask here why uh position copy and not set position okay this we rest the ca to previous uh we use copy instead of set because set will set the position to the same object so if we change the previous position the camera Position will also change copy creates a new object and uh with the same values as the previous position so that's why it's this different so don't use set but use copy here to the previous position okay so we export this check Collision because we need it check Collision checks the camera and the walls as parameters and returns true if there is a collision okay and false if there is not a collision the camera parameter is the camera object and the walls parameter is The Walls Group not array the parameter are passed from update movement function where check Collision is called okay we have this update movement that has these parameters and we get this from there because we call this check Collision inside update movement uh and update movement gets the parameters from setup rendering where it is called so we get check Collision parameters from this update movement and update movement gets this parameter from setup rendering where update movement is called and setup rendering gets the parameters from Main Js you see setup rendering gets these parameters camera Etc from MJS because we are importing them here from the files and this is the logic uh so we check uh we create this and Export this check Collision we inside this function what happened uh we for recap we create a player bounding box which is an instance of three box three that creates bounding box for this player or user we create a variable for the camera World position which again is an instance of three Vector 3 class and it creates a vector to hold the camera's World position then we access this get World position method from with a camera camera that get World position and we pass Camera World position here is Vector three and this gets the camera's World position and store it in this uh Camera World position uh you know that the camera represents always the user the player uh in in our case then this player bounding box access this set from Center and size method and this sets the player bounding box to the camera's World position and size the size here is one one one because the camera is a single point this set from Center and size method takes two parameters so the center which is the ca word position and the size which is this Vector three okay the center is a vector uh Vector three that represents the center of the bounding box the size is also a vector three that represents the size of the the bounding box yeah the size is the distance from the center to the edge of the bounding box in each Direction so the size is 11 one the bounding box will be two units wide so 111 and the two units tall and two units deep if the size is 2 to2 the bounding box will be four units wide four units tall and four units deep Etc you can read more here if you forget or if you need again and yeah we create uh this Loop to Loop through the children uh of of the walls we Loop through each wall and we get the wall and then if the player bounding box intersects with this walls bounding box with this method intersects box and we pass the walls bounding box so it's like the code is self-explanatory and this naming is very clear so if the player Bound in box intersects with the walls bounding box okay return true if not if they doesn't uh intersect return false okay and that's it for the check Collision uh function and that's it I think we covered everything and set up rendering two set up rendering which is in the rendering rendering okay here the rendering is you know if you remember the last part of the code in the end we had this rendering function which in a recursive uh does a recursive call and uh it calls again and again in makes a loop so yeah we pass this parameters which we get from Main JS we create this clock from the buil-in 3. clock it it keeps track for the time between uh the frames and yeah we create this render we extract it from MJS we have the variable that we need Delta because as we mentioned the for the Delta which is clock. get Delta basically 3. clock. getet Delta and this Returns the time in seconds since the last frame uh then we have this update movement to update uh the movement which checks these parameters Delta controls camera and walls that we you know we explained before explaining the update movement function we create this variable distance three sh and set it to eight for example or you choose to set the distance from the player and the painting okay because we need this distance to create the the the logic for the info card so if we are closer than this distance we want to show the info if we are you know away than 8 m we don't want to show the info card we hide it okay so we also create this painting to show variables and we will see why we need it we take this paintings that that we pass here as an argument that we check from create paintings uh function we Loop through all the paintings which was an array remember that we discussed before we Loop through all the paintings and this distance to paintings uh variable will be the camera that position that distance to the paintings is self-explanatory we get the distance to the painting okay so this variable here is to get the distance to the painting how far is this painting because we have this three should of eight units eight meters so we get this with this method distance two and pass the painting position and then if this distance to painting is less than 8 8 m is less than distance three should so if we are like uh 7 m away from the painting we set this painting to show that we created here to painting this sets painting to show to this painting which is lesser than eight okay in this case we know that the painting will show we will use this this with this value because we know that in this case painting to show is set to this painting which is lesser than eight units so we will show the painting and here we see if painting to show if this is true and we are less than eight we are closer to to to the artwork display the pl the painting info if not hide the painting info and this to display as uh we saw already we get it from this display uh painting info and hide painting info which is from painting info. JS here okay display display place this element and hide just removes the class show and display adds this class show because uh yeah to this element with ID painting info we add the class show when we want to show the painting we remove the class show when we want to hide because we have this in Styles in the end you will see we have a style for the painting info show so painting info. show for the class of show we apply these Styles and we remove our ad and we have the other Styles as well and and that's it I think we covered everything yeah I think we covered everything so this is the refactor I think you like it more like this yeah leave me your thoughts what do you think about it and this is for this tutorial uh let's finish here thank you for following this and uh see you welcome back developers and 3D design enthusiasts today we are journeying further into the world of 3js as we continue building our 3D art gallery first of all you can see that we have brand new textures and they are in 4K resolution for the best quality and yeah the difference is visible I think it's much much better now I have added the new ceiling the walls and I really like the floor there are details and the quality is good then we have integrated the pointer lock controls toggle so now you can see seamlessly toogle between game mode giving you smooth navigation around the gallery and also the UI interaction mode letting you interact with on screen elements at is as you can see I press the space key and the poter lock controls are disabled so now I can use the mouse S I can click and you see I'm redirected to my landing page to my shop or wherever you want the user to be redirected this is the picture that some people asked for it in the comments so I edited but yeah you whoever wanted to touch the the artwork in the gallery but you had that do not touch sign and that stopped you right well now you will be able to interact with the paintings you can touch and you can click so you can do whatever you want you can uh attach other event listeners you can add your own logic but for now I added the logic to Simply navigate to an external website which will be our website but feel free to to make your your own logic about it it's easy customizable now so you can do it uh what else else uh if that's not exciting enough for this part six uh we have introduced also a VR button for VR support you can see we have the enter VR here this is also a feature that uh someone requested me by writing me on private so I couldn't uh make it sooner and I'm sorry for that because yeah uh that's someone that wrote To Me wanted to beat you know he had this project and really needed this feature but I was very busy but in the end yeah I at least started this feature to implement it so now we have this enter VR and we need to install an extension for this because I don't have a VR device and of course I cannot test it because I would need a VR device or headsets but but uh if you don't have it but you want to implement this you can download an extension on Google Chrome and that extension is called I think webxr simulator webxr simulator yeah yes it's this one install it and then go to your project open the the developer tools and here you should find this web Pixar open it and you can see now that we have the simulator and we can choose for example we have here Oculus Quest or Oculus go Etc Google Samsung Galaxy but yeah leave it here Oculus Quest and if we press enter VR you see that the scene turns black of course I cannot test it because I don't have the headsets but it shows that it works and if we go to the console you see web XR session started because I console log this so it means that it works we will go further into this and we will explore it together but follow me on this part six all right let's Dive Right In now we'll be adding an audio guide feature to our 3D art gallery this is an awesome feature that you could use to explain your projects or simply to guide users through your gallery and for this let's start by setting up some basic control controls for our audio guide in our HTML here we will need a div uh with a class of audio controls and two buttons one to start the audio and one to stop the audio so the shortcut for that audio controls and two buttons shortcut again for bottom bottom start audio okay we have this basic controls for this now let's switch to our JavaScript and we are going to create a module called audio guide where we will handle the audio functionality so create a new module here call it audio guide and as always we import three from three okay in this first line we will import the three as we always needed and we will declare a variable sound this variable will be our audio Source okay so we need an audio Source this audio Source will be this variable let sound after having this audio Source variable what we need we need the function that will make this possible and let's call it setup audio and since we needed to exported it would be export const setup outo okay so narrow function because we will need everything here inside so we have this uh setup audio uh this setup audio will will check as a parameter the camera because we need this camera parameter I will explain everything no worse so the first thing is for the audio um like in real life we have the music uh to be able to listen to the music we need our ears right so we listen to the music with we need some ears and the same thing in 3js we need this listener that will be will act as our ears okay so a variable for that const listener we are not going to call it ears so yeah listener and this uh we will get it from the audio listener uh class from three so new three do audio listener it is oh no it is it parenthesis okay uh make sure you are writing inside this function okay because when we will export it this logic will be inside this setup audio not outside because you will get errors ex ex so we defined our first function and the only one that we will need actually this takes the camera as a parameter and now inside this function we will create an instance of this three audio listener that as we said is essentially our ears to listen to to to the audio and the last thing is uh this listener will be added to the camera because let me explain camera. at we pass the listen this means that as the camera moves the sound will change accordingly creating a realistic audio experience okay that's why we attach this listen to the cover after that what we need we will need uh to create a new object which is 3. audio to pass our listener this will represent the audio Source in our scene let me explain we have this variable that we created and we said that this will be our audio source so sound equal to new 3. audio and to this audio we pass the listener okay this will represent the audio Source now what we need we need to instantiate AIO loader which will allow us to load our audio file because yeah we need to load the file and to load the file that we will download and put it somewhere in our project to load this file we need a loader and this loader is from three audio loader and that's it we will create uh for this const const AIO a loader and this audio loader as we said will be instantiated from three. audio loader it is here audio loader parenthesis don't forget now that we have this audio loader we are calling the load method and we will pass the file path where we have uh this sound this audio and we will also have another parameter apart from the file and I will explain while writing it down audio loader. load pass the file path here that can be yeah we will add the folder sounds inside this folder sounds eventually will be the name of of the the audio let's rename our audio audio guide because maybe we will have more than one audio so that OG you know the format OG and here as I said inside this oh I'm outside okay inside we we will also pass a callback function and this callback function will run once the audio file is loaded so function that we will run once the audio file is loaded we will pass here the buffer y because because here we will set the buffer of our sound object to the loaded audio data and the nameing in 3js is always intuitive so we we use this uh methods that the naming can explain itself so sound our sound set buffer and we just pass the buffer that I pass it here as a parameter also this callback that uh will run once the audio file is loaded we will set the buffer but also we want to to to enable looping because yeah for example I want to add the background music at the moment and I want just to to Loop it uh the same thing the naming is uh self-explanatory of this method so sound. set loop and you set it to True simple as that also you might want to to adjust the volume sound. set volume and from a range from 0 to one you can choose 0.5 okay make sure everything is inside the curly brackets of this setup audio now that we have this sound and we created the loader we need uh two functions and we create the start audio the function to start the audio that we will call it and also a function to stop the audio and these two functions are pretty straightforward okay so export con start audio in this case to follow the logic uh when you create things when you create functions in programming you want that if there is a if there is a sound you want to play it but you want to check if there is a sound play it then if it's currently plain then pause it okay this is the logic because you you had the sound okay now you just want to start or stop it export cost yeah yeah yeah it's inside let's put it outside it's a separate function as I said it's pretty straightforward is there is a if there is a sound if sound if true just play it for that sound that play simple as that the same logic for stop audio export const stop audio if sound if it's currently playing you want to to stop it it's the the same thing not stop but pause so sound. pause okay yeah and that's it the last thing that we need finally we will import this setup audio function we will import it to our main JS okay we call it so we have the audio in our SC so go to main J s import this setup audio okay it's uh not an a default export so don't forget the curly brackets you know that I know from audio guide and then just call it here in MJS set up audio and you pass the camera as a parameter yeah you are passing the camera because you are using it here in the audio guide file you see you are using the camera that you attached The Listener to the camera to be able you know to to create that uh 3D experience as you move in the scene but you don't have any camera here defined in this file JavaScript doesn't know anything about this camera so yeah you have the camera here because you are getting it from setup scene and that's why you pass it here to use it also here and that's it we now have a working audio guide I don't think we have any errors oh okay I need to restart it you see here start audio guide stop audio guide yeah I need to put the audio file in my project because I don't have it but yeah we should not have any problem we will test let me add the file okay guys before we continue with the new functionality of the pointer lock controls to enable or disable them when we press a key I just want to add a small fix for the audio guide file because sometimes you may have some issues on playing the audio okay you will wait for it and it will not play immediately and this is due to the asynchronous nature of audio loading in JavaScript and how the web audio API handles playback requests and here is an adjusted version of this audio guide file that maybe should work more reliably there are just a few lines of code really so we create first a new variable and this variable will be called buffer loaded and by default it will be false okay this flag is to track if audio buffer is loaded or not and here when we are using this load method when we are are setting the buffer and setting the loop here we will set the buffer loaded to true this will set buffer loaded flag to True once the audio buffer is loaded because yeah we are using it we are loading the sound here we are setting the buffer setting the loop volume and also the buffer loaded it will be true and why because here when we are starting the audio and here we have the condition if sound is true so if there is a sound we will add and so if sound but also buffer loaded true so if there is a sound and if the buffer loaded is true so check if the buffer loaded before playing then sound. playay and that's it this is the fix and that's all it should be better now for the asynchronous nature of JavaScript in this version buffer loaded is a flag that tracks whether the audio buff buffer is loaded we only allow the audio to be played if the buffer is loaded okay so that's why we said buffer loaded to true this approach ensures that we don't attempt to play the audio before it's ready which can cause issues or inconsistencies however please know that it may still take some time to load the audio data especially for large files or slow network connections dur in which the audio cannot be played so keep in mind that all right let's continue fixing the pointer lock controls now and here we should go to the file event listeners because here is where we will make the changes for the pointer locks at the top we will introduce a new variable lock pointer which will keep track of the state of the pointer lock okay if it's true it means that the pointer is locked and we are in the game mode if it's false it means that the pointer is unlocked we can interact with the UI elements okay so let's introduce this new variable and follow me step by step so let uh lock pointer and by default it will be true and also another variable for the menu to show it uh when it's unlock or not so let show menu unlock and this by default is fult so these two new variables lock pointer and show menu unlock lock pointer will help us know the current state of the pointer whether it is locked or not simple as that show menu unlock will be a flag that determines if the menu should be shown when the pointer lock is locked simple as that okay now we should change a bit our code and what we will change are this key down key up and unlock okay so first of all we will change uh the unlock to show the menu or not and here we will change the second parameter meter which now is simply the show menu okay that we get from menu JS to show the menu which is a module separated module here we will change the bit we will add a condition let's add first a function and this Arrow function this Arrow function we'll check this condition if show menu unlock okay then we show the menu so if this flag is true then we will show the menu simple as that so we simply call the show menu okay that you know we have it imported and yeah else the show menu unlock will be false so show menu unlock will be false that's it too many comments but yeah in this part we add this event listener to the unlock event so we check whether to display the menu when the pointer lock is released and after after that we rested the flag back to the false value okay now next thing we want to do is to create a function to toggle the pointer lock so let's create this function and let's call it toggle pointer lock so function toggle pointer log it will take as parameter the controls and inside the function we will check the condition to toggle it if log pointer so if it's true the variable loog pointer which initially is true then we want the controls to be locked that's why we have the parameter controls because we want to set the controls to lock or unlock okay so without getting confused if you see the code it's way easier so the condition if lock pointer which is the variable that we just created if lock pointer what we do we lock the controls so controls. loock else if the condition is not met that what we want to do we want to set the controls to unlock so controls. unlock okay so we have the controls as a parameter we will call it in the main JS etc etc etc but also in the else block we also want to set the show menu unlock to false right show menu unlock it will be false I hope this is clear the last thing that we want is to toggle this loog pointer here so loog pointer equal exclamation mark loog pointer which is basically set the buan value to to to its the contrary so set it if it's true make it false if it's false make it true this is the meaning of this exclamation Mark but yeah I know that you already know this I'm just reminding you the basic things okay so this toggles the lock pointer variable that we created at the top just tole okay and that's it for this part of code this function is called when we want to toggle the state of the pointer lock if the pointer lock is currently locked meaning that the lock pointer is true initially we lock and V Versa or vice versa in English we also toggle at the end the value of log pointer at the end so this function is keep it up to date with the actual state of the pointer lock and this is done so now that we have this function toggle pointer lock we can toggle now the pointer lock when we press a key that's what we wanted to do right we wanted that press a key and toggle the pointer lock in game mode or using the UI elements so being able to use the mass events okay since now we are not able to use the mouse events on click because the poter lock controls won't let us so with this function we will disable or enable them based on how we want it to be so we want the pointer locks to move but when we want to click something we want to stop and deactivate them and simple as that we will do it when we press a key so this is a custom way function to to make this to solve this problem that we had that some people requested in the comments okay so we have this function toal point a lock let's create a condition no not here but we will create the condition inside of this Onkey down event because there is where the event keys are registered you see event keys in key press that we have an object if you uh forgot we have this key pressed that if you want to check it quickly okay it uh has all this uh values false or initially and then we check them if they are pressed Etc so this is to control the event keys that we press the input by the user and here on this function on key down that is the event that checks if we press a key below this condition that we already have we will add our new condition so if we press the space bar we will choose space bar for this we can use any other key but I think space bar is uh yeah it's uh better it's practical so if we press the space bar we toggle the point l so if it is true it will be false if it is false it will be true we toggle it if EV that key the same equal oh equal for the space bar is just an empty space here we toggle we call the function and that's it toggle pointer lock and we pass as a parameter the controls here this is this space bar making again the summary of this function will be used to toggle the state of the pointer lock which means that if the pointer is currently locked it will be unlocked and if it's currently unlock it would be locked okay it's a playing with words this is a convenience feature for users to easily switch between the game mode the immersive mode and the UI interaction mode that we can use the mouse events we can also add other checks for other keys that we want to use for example we can set a key to start the audio we can set a key to stop the audio we can set a key to show the menu and many other things we can do all of that okay maybe we can use uh now the Escape key so if we press the Escape key we want what we want to do if we press the Escape key we want to set the controls to unlock okay press the escape and it will be unlock also we want to to show the menu so we will set the show menu on lock variable to True uh let's do it with code so it's easier to to understand so again the same thing if ev. key equal is Escape which is the code for the Escape key we want to do a set of things first of all we show the menu we press the the Escape key we want to show the menu if we are let's say uh with the pointer locks you know we press Escape show the menu stop the pointer locks or you know the exploring mode so first of all call call show menu then uh we want to set the variable to true the show menu unlock which is uh responsible to check the state for this so show menu unlock to True also we want as we said to set the controls to unlock you don't get to be confused with lock unlock because you know for the controls but I think now you are familiar with this so set the controls to unlock also as with the menu we want to change this variable that we had at the top so the variable that which is responsible to track the state so log pointer we set it to false in this case Okay so the lock pointer is false and that's it we also have this for the Escape key okay you see I press the Escape key I show the menu and set it the unlock controls okay so it works what else we can do we can add also the enter key to start the game to start the the exploring mode so if we press the enter key what we want to do let's say uh now we have the menu okay so what we want to do and the also the controls are unlocked so if we press the enter we want to hide the menu and also we want to set the controls to lock and set the variable for that it's easy it's this the same thing you can do it without my help so if ev. key equal to enter as we said we want to hide the menu first so called HDE menu okay that you see we imported hide menu and show menu from the menu Js which we have here okay you see we have two functions show menu and high menu which basically wheel Styles they show our height simple as that where are we okay we are here so if we press enter we hide the menu also we said we want the controls to lock so controls do lock okay and don't forget to set the variable to true so the variables is responsible to you know to check to be set because with that variable we keep track of the state of the pointer logs so log pointer set it to True okay and then that's it we also have Escape we have enter and uh we have the space key okay guys I was testing it so the toggle pointer lock when we hit the space bar doesn't work and let's check okay I see a few issues here that we should fix but first of all let me change this variable name and then we fix the issues okay so these isues are two issues the first no three issues actually the first are these two event listeners here the first are these two event listeners here we should pass the event and the controls also we should pass the controls here because yeah of course we are using the controls so we should pass here as the parameter controls this is a space should be correct so the only thing to fix are these two event listeners okay so let's fix it so here on this ony down let's pass the event cre ER function and on this ony down let's pass the two parameters event and controls okay the same thing for enia yeah okay it should be okay now here we have the controls here we have the controls I think it should work now let's try pointer locks are enabled let's press space okay it works ah okay okay it works the first time but the toggle doesn't work so this is correct but the tole doesn't work so the second time that I press the space doesn't work and probably is the problem here okay I saw it here you see controls. loock the parenthesis okay we should call it this lock method and yeah I think yeah unlock parenthesis yeah yeah I think that's the issue let's try press space it works okay press again it works yes now it works this is fixed okay now that we fixed the pointer locks controls toggle we want to add the functionality that we discussed previously so we are going to help the users interact with our 3D scene by enabling them to click on paintings which will then open up Associated web pages something that uh many of you wanted to to have the main components of these features are first The Click event handling then the ray casting that we didn't cover the painting object interaction and to break it down with the explanation step by step uh let's see the code that we are going to create for that first of all let's create a new module and let's call this module click handling and first thing first we want to import the three import three front three okay and before creating the function because we need the function click handling we need two variables okay so these variables are the mouse coordinates and the Ray Caster let Mouse we create a new Vector two for this so from the three new new 3. Vector 2 and for the r Caster let R Caster new three. raycaster okay now we created this module and now we will create a function with the same name a click handling that will accept some parameters so function click handling with the parameters renderer camera and paintings arguments actually so render camera paintings okay we don't have this defined anywhere in this file but you know by now that we will call this function here in the main JS and we'll pass you know the camera etc etc I will create this function and we'll explain it after writing it down uh what I wrote and why and step by step with the explanation of it okay but uh the first thing is we want to register an event listener for the click event so each time a click happens we want to register it in the screen so later we know if this click was in the painting or not so access the renderer then the D elements and we attach an event listener to to to this uh D element sorry so add event listener and it will be a click event then with an nrow function that we pass the event to to use it and here we will use the coordinates for the mouse for the X and the Y uh coordinates okay so here uh the mouse that we created the vector 2 mouse. x and we should normalize this but I will explain after writing it so mouse. x uh we assign it to the event. clientx okay divided uh you have heard of this when window. inner width and window. inner height do you remember inner width and we normalize it for those that uh don't know what I'm talking about I will explain minus one and the same thing for the Y Y and here inner height okay here we registered an event listener on the click event okay I sorry I have just small back here this is plus we registered an event listener on the click event and each time a click happens we normalize the mouse uh position to range of minus1 to plus one for both X and Y this is because 3js uses this range to represent the screen space we then call the onclick function passing the camera and the paintings as arguments so onclick pass the camera paintings okay and this is done don't get confused by this formula here is just to normalize the coordinates for the X and the Y because 3js uses this to represent the screen space and that's it nothing uh you know to be afraid of yeah I have a small typo here the next step is to implement the r casting and we didn't cover R casting we wanted to cover it when we uh made the Collision but I found an easier solution so we didn't use R casting on that part uh since we want want to handle the click event using uh this Ray casting technique the Ray Caster to to explain it uh simply is an object that emits a aray from a specific point in a specific Direction This Ray can be used to check whether any objects intersects with it or not okay in our case we are using it to see the user's Mouse uh when it clicks intersects with any of the paintings that we have in the scene here we create the function uh on click we pass Cameron paintings then we access this Ray Caster and we have a a method here set from camera I will explain and we pass the mouse and the camera then we create a variable for the intersects con intersects and assign it to R Caster do intersect objects method intersect objects okay objects not object and here we pass uh what the paintings what we want to intersect paintings in this onclick function that we just created we use the recaster set from camera method which takes the normalized mouse coordinates for x and for y as arguments and also the camera we then use the requesters intersect objects to get an array of intersections between the array and the paintings each element in this array represents an intersection and it contains information about where the intersection occurred what object uh was intersected etc etc so we have this the next uh step would be to handle the case when the intersection does really occur so if this intersect array that we mentioned is not empty it means that the user has clicked and uh it was a painting there where we clicked and in that case when it happens we grab the first intersection uh which will be the closest painting that the user uh clicked on and we will perform our desired action in this case we will just open a new uh web web page we will be redirected to to our shop our landing page Etc so to implement that add the condition if as we said if this intersect array is not uh empty and for that in javascri scrip we check with intersect if intersect is greater than zero here we create uh first the a variable to to access the painting so the first one painting sorry const painting the first uh that we get in the array so intersects uh uh index zero that object here perform the desired actions okay we can conso log we can conso log here the the clicked painting So clicked painting and here we pass the title of it so we know what we what we click and that is we get it from painting data painting title where is it title so info title okay but this is the user data object which is here in painting. JS this user data so so here to access it painting. user data do info. tile okay since we are there we want simply to to open an external page so for that we use window. open here and we pass the link that we want to open we can simply add here the URL but it will be added here in the user data so a new property here uh URL and also add it here yeah I already edit here the URL so for that I can simply or back W okay I have it oh I have it oh yeah I have it I can simply add the link here and we also have the URL here so for that uh we can access this uh the same with painting user data info link painting user data info link open it in a new page so blank and that's it it should work the last thing here is to call this function click handling in the main JS so we can also get we can also get this arguments render camera paintings so here import it click handling okay and let's say here call it click handling and pass render camera we said and paintings right render camera paintings render camera paintings yes let's try now if it works or not we disable the point of locks first now we click it doesn't work let's see the console lock on click is not function on click why is see lower case it should be uppercase right I click yeah it was a typo disa poter locks controls click but now nothing happens oh if intersects greater than zero if intersects that length it's an array but I don't think this is the issue yeah exactly this is not the issue oh okay so this is for 3js to normalize the screen space we set from minus one to + one so this is minus here this is minus here I think think this is causing the issue yes it works that was the issue if we click here nothing happens if we click on the painting it intersects and it works so it organizes the paintings okay and this is done you see also it's console locked clicked painting vangog 2 click painting vangog 3 or vangog Guan so it works and that's it for this part of the tutorial I think we have implemented this feature that was requested we also added the audio guide maybe we go and implement the VR support for our 3D art gallery what you think it would be nice to make a tutorial on it but I will think and we can maybe add another tutorial about web Pixar tell me your thoughts and if you would like to add this webar support for our art gallery or not or if you have any other suggestion thank you for following me and see you\n"