Computational Design Live Stream #89

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right are we here we are hello good afternoon everyone this is a second oh it's been a while since i don't do live stream on the set two live streams on the same day that's kind of awesome that we're going we're back on track alrighty so this is the second live stream today and we're doing another live stream because i just happen to have a bit more free time than usual tomorrow is thanksgiving here so uh i'm gonna be cooking a little bit but not as much as i typically do so i can spare some times um um and also we are doing with this morning we started this really cool simulation of a christmas tree with led lights and i actually want to finish that today so that those of you who may have time you want to practice you want to try to create your own light sequences and then hopefully in a couple weeks whenever we organize the parametric cam community meetup then we can all meet you can share your files and then maybe i can run them through the through my trip and like everyone we can have like a cozy kind of christmas celebration sort of thing so what are we doing this afternoon we are continuing with the video we did this morning where we um were illuminating a christmas tree with led lights this morning we did a simulation in grasshopper hey nicolas hello again this morning we did a simulation in grasshopper today this afternoon we're going to we're going to learn how to create those ways of creating those sequences all right the light sequences the light patterns so um what are we going to do for that let me organize myself here i have a bunch of files so what are we going to do first i probably want to open rhino i probably want to have a rhino instance somewhere here and a grasshopper instance and yes and what are we gonna do and i have some sample files so i'm just gonna open them here on this side so that i can take a look at them those are christmas tree this is the one that we did yeah probably i have so many files i'm kind of losing track of where things are [Music] how's everyone doing in the meantime huh hey teo mikhail hey mikhail i've seen you a lot recently on discord how are you doing good to see you all right hi from turkey i love turkey such a beautiful country okay and then what else so what i need to find a couple of files give me one second oh i see i see what this is what i want okay so we're going to do is from this morning we're going to start with the part that generated the christmas tree simulation the simulation only okay so we're going to save this christmas tree and we're going to call this sequences and i'm going to remove all of this and we're going to have just the points here and add to group yes and we're going to have the points over there and then we're going to here have the points all right and then [Laughter] is that what we do we when we write a lot of grasshopper we're psychopaths then i must be a really sick psychopath uh that is weird we may need to take a look at that because it's not normal mikhail that's just uh something is you may have some kind of restriction or some kind of uh have you tried running visual studio in admin mode and also have you tried saving those files in a folder that is not in like a simple folder i'm going to call it like somewhere on your desktop so that you can have access and you don't have limitation restrictions somewhere that is not on a cloud service so that the file path is not super huge and you don't have white spaces try saving all your files in like a simple route and running everything right in right now and running visual studio both in administration mode in admin mode so give that a try if you because that i've never run into that issue it's very strange what windows are you using 11 are you with windows 11 already anyway christmas tree sequences i'm going to save this and then [Music] okay um all right hey chandra how are you doing good night okay so we have this and i need to remember oh that's very strange windows 10 i'm running that i'm running everything on windows 10 and it's working fine i don't know give that a try i don't know what else can i suggest anyway um so which sequence are we going to do i think we're going to start with um uh all lights let's see if i can just say i'm um oh light passing with this light offset all the lights pulsing randomly and what else can we do we can add color and then we can add color we can for example add color [Music] we can do the moving plane and then moving rainbow those could be interesting okay so we're going to create six sequences and then the video that i'm going to record is going to be what is it going to be the video that we're going to record is going to be what's going on here oh sorry oh i just got a notification that i'm going live okay and the video that we're going to record is going to be it will be an introduction then it will be it will be what is it going to be and it will be uh what is it going to be it will be the introduction then it will be the sequences and then it will be simulations yeah with the first the first sequence we will plug in the simulation so that we can verify we're doing this right then the second one and then we will i will go through this and then i will say okay let's go to the tree and give it a try and then i will record that later because i can't do that right right now and then after that i will go back and then i will i will close the video i guess and then the intro is going to be showing the sequences showing the sequences but probably not showing the i'm probably not showing the actual results nah not resetting this because i don't want to come back and also i can leave that for the end of the video okay all right okay so let's start oh and i need to have a an example so i'm going to open some visual studio code and i would like to have this one and i would like to have this one as well can i not scroll oh okay i kind of like this as a background kind of nice right as a background like the colors all right all right beautiful and should i start from the simulation let me think about that for a second should i start from the simulation maybe i want to start from the simulation okay so let me start from the simulation and then it's going to be called sequences okay and then we have this and then we have this and then we can simulate this okay okay so i think we are ready to start okay um okay so let's get started if you remember from the previous video in this mini series which um maybe the link is coming up as a card here on the corner or it's also in the description of this video if you remember from the previous video what we did there was first of all we were able to load the l the coordinates of a string of led lights that was wrapped inside of a around a christmas tree and how we had calibrated that and all this stuff you can see matt's video uh for that but basically we had generated the coordinates we could load them from a csv file so that we could see in three-dimensional space we could see a representation of those led lights so that part is here this was where we were loading those coordinates and created a family of points and then in the previous video we were also able to load from a csv file a different one we were able to load a sequence of how those led lights needed to turn on over the course of a certain amount of frames in a in a simulation of an animation for example we were able to load this csv file which looks something like this we're going to take a look at that into a second and then we wrote this custom script that was able to go through all those frames at a particular interval and connect it to this custom rendering pipeline with particular colors and particular meshes so that at the end of the day the result was that we could press play here and we could see an animation of what type light sequence looks like for all the points all the led lights on the tree that were represented as tiny spheres in this particular this in particular this csv file this this sequence had been designed to take a cl take a look at where those points are in three-dimensional space and create this animation of a plane that at any particular instance all right now this in the previous video we generated we broke down how to simulate this whole environment but we assumed two things first of all we assumed that we had a file with the coordinates of the leds and again i'm not going to get into that in this series of videos because um that is like a little more complicated that i would like to anyway and we still haven't figured out the process very cleanly yet but it also assumes that you have this other csv file that represents how all those led lights get illuminated over a sequence of steps in which case in this case we're going to call those frames so what that looks like is something like this so i have in my project file i have the coordinates of the tree and i have this moving plane csv file which is the one that has pre-recorded this motion this animation of the lights turning on as the plane virtually travels the z direction what that looks like is something like this the csv has a particular format and this is a particular format that we me and my students designed so that exchanging these animations between different trees was a little easier and the the way this csb is formatted is in the following it has the first column that tells us what is the id of the frame and it's basically a bunch of consecutive numbers from 0 to whatever frame number it is and then for every led light we have three columns representing the rgb colors of that led of that led light for every frame so these are the three columns for led zero these are the three columns for led1 led2 each one of them being the rgb colors so you can see and there's three columns for every light you can see if i scroll all the way to the end the last three columns are for the light 499 which means that this simulation contains data for if we were to look at this simulation we can see that clearly during the first 20 frames there's nothing happening for the led 0 1 or 2. you can see that nothing is happening but then for during frame 21 you can see that the led 0 gets values of 23 for each one of the channels and then it increases and then it increases all the way to 244 and then it decreases down all the way to zero in frame 39 and then from there on it is zero until the end of the simulation what that means is that if the simulation takes 150 frames this led led 0 is going to go from absolutely dark it's going to go to very very bright and then after that it's going to decrease all the way to zero and it looks like led 1 has a very similar pattern and then led 2 has also a similar pattern and led 3 etc etc what this tells us is that every led [Music] as soon as it's time on the simulation depending on where it is in the z height whenever it's its turn then it will turn on a little bit and then it will turn off all right this is how we can encode these pre-recorded animations into csv files and then can be replayed on the system that we have attached to to the tree but because this is a csv file i am opening it with excel spreadsheet which gives me like a very clean and nice tabular view of it but i just want to remind you that csv files are basically text files that contain values separated with commas so if i were to open that file that same file inside of a text editor like visual studio code for example you could see that it's basically rows of zero zero zeros and then rows of values is just the same kind of view it's just that in in a cell express sheet the columns are a bit more aligned it's a bit nicer to read okay so the if what we want is to create a pre-recorded animation that then we can play on the tree then in this particular case in parametric cam the example that we are doing is relying on the fact that someone has the capacity to generate a csv file that contains this kind of code so the first the first column is the id of the frame and then after that it's just triplets of rgb values for each one of the leds if you're able to conceptualize an animation and then dump or create a set of numerical representations that represents the state of the light at every frame then we will be able to re to replay this and in the tree that we have because the tree that we have is ready to take this kind of information and play it at a certain frame rate okay so design animations boils down to conceptualizing what we want to do and then be able to translate that conceptualization into a stepwise framewise list of what all the colors of each one of the led lights should be at any particular instance of time all right that's a general idea so what does that look like in grasshopper world well in grasshopper world let's let's also full disclaimer grasshopper may not be the best tool for doing this because grasshopper is not great at animations or dynamic things and also but grass operation is perhaps shines a bit more if we do animations that are specifically uh taking into consideration this speciality of this all right but so maybe grasshopper could arguably not be the best tool for this but since we already did it here and so we're just going to go for it so what we're going to try to do then is we're going to try to live on the we're going to try to build on the example that we did before where we had the point coordinates and the simulation part but instead of loading the sequence from a file that already exists in this case what we're going to try to do is we're going to try to generate the file ourselves so that we can save it in a file that we can load on the tree afterwards but at the same time we can link that file to the simulation pipeline that we have here so that we can simulate these things as we are designing them so what is that going to look like well first of all i'm going to remove the loading part and i'm going to keep this i'm going to keep this simulation part here and then i'm going to generate my first c sharp script component where i am going to where i'm going to create my first csv sequence all right and what is that going to be for a sequence so i don't know well you can't see the the the three the lights anymore but we're going to start super simple we're going to try with that we're going to start with a simple sequence that what it does is it doesn't look at where the led is it doesn't look at it's just going to turn all the leds on very slowly and off very slowly on very slowly and off very slowly we're going to call that a pulsing animation because it's going to feel like on off on off and all the lights are going to do it at the exact same time so that it's a bit easier for us to start warming up all right so let's take a look at how we're going to do that okay hey karthik good afternoon so where are we going to do that i'm going to start by creating a c sharp component that i did here already and i'm going to say that i want to the output to be a csv file and then i will take care of saving that somewhere in on the file system at some point or whatever and then the the first input that i'm going to do is i would like to um i would like to take the leds as an input all right and these leds designed before because there's a lot of information that we can get from that these are going to be of the type which you can see here because it's going on my other screen are going to be of the pi of the time point 3d and then i'm going to ask for list access because i would like to be able to see all the points at once so in the first sequence it's going to be super easy and we're actually going to have to deal with um with uh others we're going to first start to deal with other stuff here so okay so we're going to start by designing what is the algorithm and first of all what we're going to do is we're going to prepare the basics of our csv file the basics is that if you remember the file the first line what we're going to do is we're going to create a file as a sequence of lines and each one of those lines is going to be a long string that we're going to generate so the first line is going to be a long string that is going to contain all this stuff here all this stuff here is first of all is the id of the frame and then after that is going to be triplets of this rgb plus the number of the led that we're targeting we're not really we don't really need this very strongly but it's good to remain consistent and it's a good exercise to do so first of all we're going to create the csv file and the csv file is going to be a list of strings each one of the strings is going to be one of the lines so for example i'm going to call this rows and that's going to be a new or i can call this csv for example and that's going to be a new list of string objects right but if i do that then i'm going to have a clash with this name so then i'm going to maybe just uppercase this okay so csv uppercase is going to be the output and csv is going to be the list of um the list of strings all right and then i'm going to add the header the header as we said looks something like this it starts with the id of the frame and then it starts with a sequence of 500 triplets of rgb and the name and the number of the um of the led so what that what does that look like um so [Music] first of all how many lights do we have in this case uh we can do led count it's going to be equal to leds.count however many are coming from the input all right so all right that's working good what is the next thing that we want to do we're going to add the header the header as we said i'm just going to copy and copy this it's going to look looking like and then i'm going to copy this here all right okay so what that means is i'm going to create a variable that i'm going to call a row all right and i'm going to initialize that to frame dot id and then a comma all right so now i have the first part of this and then uh i will continue the rest but so that we start getting some outputs so let me say csb dot add i'm going to add this row and then the outputs so that i start building already something that i can see is going to be that csv file i can now connect the panel here and you can see that uh i have the very very beginning of my of my csv file all right is that looking good that looks good to me what is the next thing that i would like to do the next thing is i need to iterate 500 times or however many led slice i have and add this sequence to the to the to the to the row all right so what i'm going to do is i'm going to iterate i equals 0 i is less than led count i plus plus and then what i need to do is to the value of row i'm going to need to add the following i'm going to need to add the um i'm going to need to add first of all r underscore plus the value of i then comma then r g and underscore and the value of i plus and then comma b underscore and the value of i okay if i do that let me see if this works i'm going to run this and you can see that it's kind of working but i have here i am missing the last comma here all right so i could do that i could just add here the last comma but that's not going to be great because i don't want to add that last comma unless we are in a in a row that is not the last one because i don't want to end so if you look here if i go to the end of the csv you can see that the last column doesn't have a comma at the end so what i would like to do then i would like to say if i is any different from a led count minus one so if i is different than 499 then add the comma otherwise don't do it so what i'm going to do is row and then i'm going to add the comma now if this is the case all right and i'm going to add the commas there and then it looks like rgb rgb it looks great and if i scroll the way down there is no oh you can't see that with my head there is no trailing comma here all right so it looks like that is doing what we want all right okay so we have the header so we are good now what is the next thing that we need to do we need to add for each frame we need to add um we need to add a row with the led intensity for each one for each uh for each led okay at this point i think i may want to uh what do i want to do i may want to uh well at this point i may want to to show [Music] i may want to do whiteboard is that what i want to do i may want to okay how am i going to explain this i probably want to start here now then [Music] before we actually start designing any animations or anything we need to figure something out and we need to figure out how many frames does our animation have so that will depend on many things but it will depend mostly on first of all how long do we want our animation to be do we want it to be 5 seconds 10 seconds an hour whatever that is right and then we will also need to decide how uh how dense that animation is so how many frames how many changes in the color of the lights we want for each second think about the video it's the exact same concept we need to decide how many images per second we want to show inside of one inside of one second and then if the video has 30 frames per second and it's 10 seconds long then all the images together will be 300 images right so same idea here in order to do that i'm going to add two parameters here one of them is going to be fps which is going to stand for how many frames per second we want this animation to be and the other one is going to be the duration in seconds all right so fps is going to be an integer and duration is going to be also an integer and then i probably want for example here and probably one animation that is about 60 frames per second i was trying that on the tree and it worked pretty well and then i want another that is going to be the duration is going to be for example 10 seconds all right then it's going to be very easy to just say to figure out then um calculate uh total length of animation integer frame count is going to be equal to fps times the duration so if we want 10 seconds at 60 frames per second then we will have 600 frames all right and then uh we're not going to get so i'm going to make like a fake csv which is going to be i'm basically going to create empty rows for um for i'm going to create empty rows for all the led lights okay so that we can have like a skeleton of uh what this looks like and then after that we can start modifying the skeleton to add more or less things so what i'm going to do then is i'm going to create first of all an animation that is absolutely nothing okay so all the leds are always black and but i just want to try and see if i can get through all the process together but then uh i'm going to design uh rows generate rows for each frame so what i'm going to do here then is i'm going to say for end f is going to be zero f is going to be less than frame count and then f plus plus then this is going to be the amount of frames okay and uh for each frame i'm going to create a new row so i'm going to say well i'm well what i'm going to do is i'm going to reuse the variable that i had here that i created row and i'm going to initialize it to the frame count so that's going to be f all right and then i'm going to add a comma here all right then here i would calculate the values for each led all right fine and then whenever that happens and then after that um add this row to the csv so what i would like to do then is i would like to say csv dot this thing that i just did should give me now a csv file i'm going to turn off wrapping and so that you can see that the csv now has the full length etc but then each one of the rows now starts properly it starts with the name of the frame and i get basically 600 frames because i was working at 60 frames per second for 10 seconds okay that sounds about right okay so then how do i then add all the rgb values for each one of the led lights well the way i can do that is here and again i'm going to start by just turning them all off okay so nothing nothing fancy about that so what i'm going to do now is i'm going to create a for loop where i'm going to iterate over i equals 0 i is less than the amount of led so led count is that correct led count and then i plus plus all right and then what i would like to do here is i'm going to declare outside of the for loop i'm going to declare three variables in r then i'm going to initialize to zero uh g that i'm going to initialize to zero and then b that i'm also going to initialize to zero and i'm going to be reusing those variables to calculate things once i'm ready for calculations okay but then for the mean in the meantime because they're all going to be zero what i'm going to do is that for each led to the row i'm going to add the values of those three rgb colors again i'm not going to uh here at some point i would calculate uh values rgb values for each uh i'll calculate its value for each um led right and actually why don't we just do this so i'm actually going to do r a r g m b we're also going to calculate alpha okay and then here um alpha is going to be fully is going to be uh fully opaque so that's 255. then in green r is going to be zero for this led light g is going to be zero and b is also going to be zero okay for this one all leds are black okay and then what i would like to do now is i would like to say for this color the row uh actually i don't really need the uh the alpha we did for the simulation but we don't need to generate it here so rgb is going to be zero and then what i do here is add these colors to the row so i do row is going to be equal to the value of r plus a comma plus the value of g plus a comma plus the value of b plus a comma oh sorry the value of b and then if i is different from led count then to the value of row i'm going to add this last comma okay so that for the very very last element i don't have that beautiful so let me run this and you can see that it looks like this is working all right so i have zeros all through all right and this was not very exciting but at least we got the basics covered all right the basics cover because now what i would like to do now is i would like to write this to i would like to write this csv file to somewhere on my on my system so that i could send this to so that i could send this to the christmas tree as far as i know grasshopper doesn't really have a a component to save to the file system or i'm missing that i'm not really sure but um we can write this on our own so i'm going to create a new c-sharp script all right and then this is going to be the csv that we want to write and then this is going to be the path in my system where i want to send this to the csv is going to be a list of strings all right so that's going to be of the type list and this is going to be a list of strings which is exactly what i'm getting out of here and then the path is going to be a simple string all right where am i going to save this so for example i believe that right now my workings folder looks something like this so for example i'm going to write this here dex desktop christmas tree etc and the file name is going to be for example all black dot csv all right old black dot csv beautiful if i do this oh sorry no if i do this and i connect this here um and i don't really need an output because this is going to be the output of okay and then what i can do here is i'm going to i'm going to say first of all i need to write my csv to somewhere on my file system the namespaces in c-sharp that we use for writing to and reading from the file system are this so that's going to be system dot io and then using system dot text all right so what are we going to do here what i'm going to do is i'm going to say file dot write all lines this is going to take a string as a path so that's going to be the path and then the content is going to be the csv that i want to save all right and then i have something additional which is that i can basically that i can also add which encoding do i want to use this is useful because depending on which system do you work with if you rely on your default encoding the files may not be compatible between different systems so it's always useful to stick to a default to stick to a an encoding that you know and for example i'm going to choose here encoding dot utf-8 i could choose ascii but utf8 is pretty much the one that is taking over all right so if i do that then let me see if this is going to work i'm going to dock this here and i have my file system i have this so if i run this i can see that i have now this new csv file called all black if i up if i if i turn it on if i load it you can see that i have the 600 rows and that all the pixels every channel for every pixel is purely black if i load this i don't know what i am yes if i load this on my visual studio code you can see that everything is just zeros is a very boring sequence okay but at least it works so we have the csv generation part figured out and then i'm going to minimize i'm going to minimize this so this is figured out now a few things that i want to do writing and reading from the file system that can be tricky and can be very faulty because if the file is busy with some other um some some other processes looking at the file it's like whatever you may not be able to overwrite it so it's very typical to wrap things that involve file system manipulations wrap them into try catch clauses all right so that if it fails it gives us some warning so i'm going to wrap this as a cache i'm going to say i want to read an exception and then component dot add time this so this component i'm going to add a runtime warning and then grasshopper runtime message level dot is going to be an error and this is going to be i'm going to add here could not save file ever and then the error is going to be whatever we got from the exception all right so that's a very difficult thing otherwise i'm going to print to the output file successfully save all right and um maybe just for the sake of it on for example we can add date the date time do we have date time dot now yes okay beautiful if we do that and if we plug here a panel you can see that yeah this was fully successfully saved on the 24th of november 2021 that's why i'm recording this at 3 21 my time and if i recompute everything you can see that this got saved again and the date updated so it's a good it's a good feedback to see all right beautiful okay so we have now a system to generate the most boring light illumination on earth we can save it to our file system and we can also now plug this csv into what we did before into the simulation and run this simulation so for example i'm going to turn off the led the the cross i'm going to run this and you can see that i'm going to reset this [Music] input string was not in the correct format i don't know what that means or oh wait so maybe this was expecting the csv file to not have a header correct maybe that's the case so i may need to modify this and remove the header from here and plug this in here i believe that was a problem yes so yes so this simulation expect to not have the header so we could actually save ourselves a header honestly uh save ourselves a header and a headache okay but it's working it's animating we see nothing because there's really nothing happening here but it's working okay beautiful so how can we now start generating sequences that make any sense whatsoever all right let's start let's start simple saeed it's been a long time and good to see you i see you're still alive your phd is not letting you have fun huh all right so what are we going to start are we going to start oh this video is going to be super long well better long then um anyway yeah where are we going to start okay i was going to do the pulsing light as this as the first example but uh for the sake of effect and impact why don't we just do something real quick why don't we try to just generate absolute random blinking all through the all through the simulation i think that could be a quick one to do so i'm going to group this all right and then i'm going to remove this so i'm this is the first generation which is basically all black and we're going to call this flush because flash is one that we can use to we will see we will see very soon we can use this one to basically clear out the previous uh previous so i'm going to call this flush all right and that's going to mean to remove whatever lights were left over from a previous sequence all right then the next one i'm going to copy and paste the whole thing and i'm going to call this complete random linking all right what that means is here random blinking all right that's going to be the name of the csv file random blinking is going to be that at any frame what i'm going to do is i'm going to calculate a random value between 0 and 55 and i'm going to turn each led with that random with that random color with that random uh that random color so for example what i'm going to do here is i'm going to say i'm going to calculate the values for h led light first of all here i'm going to create a random object generator a random generator and i'm going to say random rnd is going to be a new new random object all right is this going to work yes now before i calculate the values for each led light what i'm going to do is here i'm going to calculate a random value between 0 and 1. and between 0 and 255 so here what i'm going to do is i'm going to calculate random is going to be is going to be the following i'm going to take the random object and i'm going to calculate get the next double no sorry i'm going to get the next which gives me an integer already so that's great integer and the minimum value is going to be 0 and the maximum value is going to be 255. so 256 because it turns out that the if you look at the specification of the random number generator in c sharp random numbers between two domains can have the value of the minimum boundary but they will never have the value of the top boundary so if we want an equal distribution that actually sometimes yield the value of 255 then the maximum value needs to be 256 which is guaranteed to never to never be produced by the random number generator okay so for all the leds i'm going to generate the same random number and i'm going to use that same random number as the rgb value what that's going to mean is that if i do that look at what happens in the end in the csv file every triplet got the same value and all the led lights have the exact same value what that means is that every frame the whole tree is going to get a random gray or a random value of the light but all the leds are going to be the same and then for the next frame is going to change it's going to change it's going to change let's take a look at how that looks like from a simulation standpoint i'm going to plug this in here i'm going to reset and then um something is not working what some this something something is not working let me see what is going on let me take a look oh okay all right give us the silliest mistake so i plugged in the output of the csv saver the thing that saves the file where actually i should have plugged in the output of the of the actual csv component so yes so this is here and then you can see uh the whole tree is flashing all right so that is not great so i mean we could we could illuminate the tree like this but it's just not nice so i'm gonna stop it because i i i don't like that at all so what i would like to do then is just get every blinky every led light its own randomness so what i'm going to do here then is for inside of the for loop where we iterate over all the led lights so i'm going to do is i'm going to calculate a new random number for each led and then i'm going to make all the rgbs equal to this random number so that we have a so that we have a um so that we have a scale of grace all right and i see indrajit on the chat welcome indrajeet injojit has been the mastermind who has helped me put together um this exercise so this the treat and to build the tree and to write the code to run the calibration et cetera thank you very much indrajit for all your work now as i was saying um now if we move this random into the for loop that we use to iterate over each led light then one different random value will be generated for each led light and then we can assign that same number to the three coordinates rgb so that we get a value of gray and then you can see that already we got something much nicer so you can see the triplets 2 10 32 104 and then next frame blah blah blah whatever and if we simulate this now you can see that well it's also a caesar but um it's not so terrible you know but it's like a random blinky of of of some kind okay beautiful so how can we write a version of this that instead of being a grayscale also blinks with different uh with different colors of course we can and then what we're going to do is we're just going to copy and paste the whole thing and then random blinking with color and then i'm going to save this random blinking and then i'm going to add here a hyphen color all right and then here it's just going to be as simple as saying well we generated a random value and then we use the same random value for rgb so this if we want colors then the only thing that we need to do is going to be as easy as saying well each time we generate the green the ground the the red or the blue we want a different random value for each one of the channels if we do this it's going to be complete chaos but you can see that now each one of the values of the rgb is like all over the place if we plug this into the simulation then you can see that i now have like random colors and then this is going to be ah i don't know how i feel about this i really don't like this kind of effects i'm much more of a minimalist here so but as a baseline we already got something going on and this in the tree will definitely look very flashy um not sure that i'm happy with it but it will be whatever okay so can we now go back to the basics and create a sequence that is a bit more elegant okay let's do that so now let's try to break down how to create a simple simulation where all the led lights pulse like they go on and off but in a very smooth transitional way all right which i feel is going to be much more christmasy but before we do that um we're going to have to i would like to break down the logic a little bit on the whiteboard let's take a look at that okay whiteboard i want to explain that we're going to start with the value of zero so um yes so i'm going to start by saying okay we're going to imagine that we have a scale all right and that scale goes from the value of 0 to the value of 255 and at that point what i would like to do is i would like to draw that over time we would like to value of the led light to go from zero to one to zero to one something like this right i will do that as what that means is that what we would like to do is we would like to say well if we plot that in a two-dimensional graph we can see that what we would like to do is if this is t [Music] let me draw this again okay if this is t and this is the value of brightness then what i would like to do is i would like to start from here and then go here and then end here so something more like this okay and then go over again where this is going to be zero and zero and this is going to be 255 why can't i not oh you can see it but i cannot weird and then what else do we got [Music] so we need to now remember that my okay so it looks like my screen is frozen okay i don't know what's going on so i'm going to disconnect and connect again okay i'm going to connect again i don't know where my okay so here all right okay so [Music] what that means is that when if we now know how we're going to discretize time what we will want is for each value of t we will want to find what the corresponding value of the b has to be for each frame okay beautiful with that done um okay um the way i would like for us to think about this problem is the problem of discretizing time and thinking of an animation that evolves over time how we can chop that full continuous animation into units of time that in our case are going to be frames and then how can we calculate the values of illumination for each one of those led values based on where we are along that time span that we're targeting so from a numerical standpoint this could look something like this for so for example imagine we look at every single led light and for every led light we know that the range of values that it can get is somewhere from 0 to 255. so we know and we're we're doing monochrome for the time being we will get into rgb later on so if we think monochrome from black to white then the range of values that it can get is from 0 to 255 since we want to create an animation that starts from black and then it pulses into full brightness and then it pulls his back into black then if we think of this over time what we would like to do is for our illumination value our brightness value to start somewhere here right and do something like this like slowly accelerate or to 255 decelerate and then go back to the value of zero more or less all right if we were to look at that exact same animation but we were to plot it in 2d by saying let me create a graphic where one axis is going to be brightness the same one the vertical one but the other one is going to be time if i think of my animation what i want to create is something like this i want to start at the very beginning of my animation with the value of 0 then i want my animation over time over half the time to get to the maximum value in this case 255 and then symmetrically by the end of my simulation i would like it to go back to the value of zero again that is actually possible if we start thinking of time as something that we can discretize in individual units and because we know how much time we want our we want our um animation to last 10 seconds 15 seconds an hour whatever that is and then we also know how many frames we're going to be rendering in this by second 30 60 whatever that is then it's very easy to calculate how many frames all together our animation should have each one of these tiny bars and then it will be just a matter of finding a numerical rule so that for each one of these units of time the frames we find what the corresponding value on that curve is going to be all right so for each sum of the frames we calculate what the value of the brightness should be at that particular instance of time for this particular example because it's going to be a super simple start from black uh go to maximum and then smooth back again you can see how i'm probably going to be using a sine wave because uh i'm because the sine function is a function that for any particular value between 0 and 2 pi or tau for any particular value you can you we know that that function oscillates between the values of of 0 to 1 to 0 to -1 all right so let's let's start by building the prototype with the sine function and then let's see what we will need to do to tweak that so that it looks exactly like this all right let's take a look at that okay and i'm going to call this pulse pulse unicorn all right back in my grasshopper definition i have gone ahead and copied the flush so the pure black uh the pure black animation i copy pasted it here and now i'm calling it pulse uniform all right and then i'm going to go into the code here we have the algorithm we prepare the header the length of the animation etc we generate the rows we calculate the values for each led and then here we calculate the values for each led all right beautiful so for this one what we're going to do is if you remember we said we need to divide time in the amount of frames we've already done that we know how many frames all right we need to we need to we need to calculate four but then because we want to go from minimum to maximum and to minimum and we're going to be using the sine function what i would like to do is because the sine function goes a full cycle from 0 to 2 pi or tau what i would like to do is i would like to calculate what is the increment of the angle that i need for the sine function in order for um in order that matches the amount of subdivisions that i that i have in my timeline what that means is that if my full cycle is tau or two pi and i have 600 frames i need to divide tau by 600 frames to know what is the increment of in the cycle that i need for each one of my frames all right so what that looks like is i'm going to calculate here um [Music] uh [Music] angle i'm not going to an angle angle step for each frame so i'm going to call this uh value for example i'm going to call it fita all right and that's going to be theta step because we have what i want to do is to math pi divided by the total amount of frames so frame count all right and this is not going to be an integer it's going to be a double beautiful what that means then is that for the values of the leds here for this frame i'm going to calculate the value of theta so the value of the angle for the sine function that i'm going to be using the value of the angle for the sine function that corresponds to this particular frame and because i have this step so the only thing that i need to do is i need to multiply that step by the amount of frames that have elapsed so that's going to be f all right let me just print this so that we understand what this is coming for so theta so i'm going to say frame f plus and then here a theta of whatever that is let me print that to the console all right and so that we can see this i'm going to plug this in here so you can see each frame has an associated value of theta from 0 to 2 tau which is roughly 6.28 all right that's going to give me a full cycle from 0 to 2 pi now i'm going to here i'm going to say well what i would like to do now is i would like here to calculate for this theta what is the sign of that of that um what is the sign of that of that value so i'm going to calculate the amplitude i'm going to call it for example and then i'm going to say that that is going to be the sine of theta for example and that's going to give me a value between between -1 and one so for example and then i'm going to go here uh amplitude amplitude is going to be equal to m lead all right i'm going to print that to the console and now you can see that this is going to give me a value that starts with 0 is going to go all the way to 1 somewhere by the middle of the simulation so that's going to be 150 and then it's going to go back all the way to 0 at the middle at the center of the simulation so that's going to be here this is 0 it's just a number with a very small decimal and then at 450 i can probably expect minus one right minus one and then all the way at the end i can expect back to zero so this is looking good it's not exactly from 2 to 55 but we will work with that in a second okay so what i'm going to do now is because i have amplitude what i can do is i can say well i'm going to do amplitude times 255 times the amplitude all right that's going to give me values between all right and then you can see that uh i cannot convert explicitly to an integer so i need i need to convert this to an enter all right so this calculation needs to be casted to an integer all right and that is still not an explicit conversion okay so maybe i need to round it math.round and then i need to round this thing here and then i'm going to i mean i could do the same thing right so this is going to work and then you can see how the values for the csv start at zero three blah blah blah the increment all the way to 255 on frame 150 which is kind of nice and then at frames 300 they're probably going to drop to zero right and then i start getting negative values which i will deal with later because we can't have negative values here so if i animate this now this is going to look you see it's pulsing is pulsing it's becoming blah it's becoming white and at 150 is going to max out it maxed out and then it's probably going to go dimmer it's going to go dimmer and then we are now at negative okay and because we're not negative it fails because look at the look at what we get value of -3 is not valid for a red for a red channel okay all right so what can we do about this so what you can see is that what i've generated right now is something that because i'm using the sine wave the sine wave goes from zero to basically the value of one then the value of minus one and the value of zero okay which is not what i wanted so what i wanted first of all is to go from 0 to 255 and that's why i multiplied it for by 255 but it turns out that i also get this area here which is all negative values and that's probably not what i want okay so what can i do it feels like something that would be interesting is to take this whole curve and somehow squish it so that it could fit here right and i could have a perfect cycle correct so that would be great and that would be great so the way how can i do that well i'm going to do some very simple numerical rule and if i right now have a curve that looks something like this if i want to squish it by half the only thing that i need to do is i need to multiply the value of the sign by 0.5 and then if i want to take this curve and move it up the only thing like this offset it the only thing that i need to do is i need to add another 0.5 to that value to the result so let me show you what that looks like so i'm going to say i'm going to say uh where am i oh not here what i'm going to do is i'm going to say here for the value of the brightness okay the value of the brightness that i had was this thing here correct that's the value of the brightness that i had and this was brightness and then this was brightness and this was brightness all right so this was what i had so because i have the amplitude here what i want to do is i want to multiply this whole thing by 0.5 if i multiply this whole thing by 0.5 then you can see that now the value of the amplitude here is going from 0 all the way to 0.5 at 150 which is you see one at 150 which is a quarter of the simulation then it's going back to zero at 300 where are we 0 300 and then negative and then positive so we have squished the whole thing we have squished it by by half and now what i want to do is i want to move the curve all the whole thing up in the positive direction by a value of 0.5 so the only thing that i need to do is to this i will need to add now here to the amplitude i will need to add another 0.5 plus the resulting value of this theta if i do this then you can see that now the value of the sine is going to start at 0.5 is going to go all the way to 1. then it's going to go all the way back to 0.5 and then it's going to min at zero point at 150 sorry a 450 is going to become zero and then it's going to go all the way back to 0.5 okay so if i run this now you can see that if i reset now i can run this and it starts at half gray and then it goes all the way up to maximum at 0.55 and then it's slowing going down it's going down very fast to zero and then it you see how it slows down it's slowing down at zero and then it goes back up to zero point zero 0.5 all right beautiful the last thing that i made just because i have ocd the last thing i would like to do perhaps is you see how the result of this is that we start the simulation at 0.5 at half brightness so if we start at half brightness then the pro then it's not really nice so what i would like to do is i would like to start here with the value of zero so the only thing that i need to do is i need to move the whole curve the whole sine curve a value of a of half pi or a quarter tau so that so that i need to offset it by this distance so that the curve starts here goes here up and then does this all right how can i do that well that's going to be super easy here when when i was doing the calculation for the sine wave in the amplitude then it's just as simple as adding to the value of theta a value of a quarter tau or in this case half pi so to theta i'm going to offset whatever it is i'm going to offset it by 0.5 times math dot pi and if i do that you can see that the very very beginning is 255 up so i actually missed the sign it turns out that it's negative i need to offset it by minus 0.5 math pi and now the simulation starts at zero starts at zero and then the whole thing pulses all right oh sorry you didn't see any of that oh sorry sorry i did that with the with the wrong so this is here so what i did was here where i'm calculating the amplitude i did i added to theta i added a negative 0.5 math by or a quarter of the full cycle of the sine wave okay and that's it that is a pulsing animation of the whole tree all the led lights pulsing at the exact same time how does that look like huh it's getting exciting huh so but you know where we're going with this now right we are going to now try to see if we can make each one of the led lights pulse at its own pace at a different as a different add a different uh not amplitude yes at a different with a different offset let's give that a try oh boy this is going to be super long paul's uniform ah [Music] close uniform pulse range what i have done for this one is i have copy pasted the pulse uniform i have pulled i've copied it here and i'm going to call this pulse random all right and what this is going to be is just that can let's take a look at the whiteboard first if we follow the same logic we were following before then uh when we were thinking about the curve and how we were moving it we can see how what we chose for our animation is that all the leds started here at zero and they all followed the same curve at the exact same pace but if you think about how if we want each one of them to have their own cycle then it probably is just as easy as deciding that each one of the led lights is going to start at a random value so for example one of them may start at zero another one may start at zero point at 100 another one may start at 200 and then each one of them over time is going to change at the exact same rate but because they started with an offsetting value this will lead to this one for example reaching maximum earlier and then ending here but then ending up a similar value and this one here may reach this super early and then this one here may reach this value like this you know uh the drawing is not great but another one here may it may do something like this you know so you see where i'm going with this it's going to be just as simple as deciding for each led light um having an initial value of the offset of where of the angle that we're using for calculating the sine value and then using that as a way of having each one of them maintain its own cycle all right let's take a look at what that looks like so this is going to be something like this so we are going to say before we start creating anything i'm going to here i'm going to generate generate random initial angles for each led light the way we can do this is for example i'm going to create a list of doubles so level initial theta and that's going to be new list of blah blah blah and okay and initial doubt all right and then where is it that i created the random [Music] uh i don't have the random number generator on this one okay so that's fine so i can say rand random rand it's going to be equal to a new random all right beautiful now what i can do is i can save i'm going to iterate over all the leds led count and then i plus plus and then here i'm going to say i'm going to calculate a new random number double uh random fit okay and that's going to be equal to random and then give me a next double the next double all right what this does is that it generates a number that is random between 0 and 1. because it's between 0 and 1 we want this value to be instead a random value between 0 and a random value between 0 and 2 and 250 sorry um and 2 pi so that so that we start at a different place in the cycle of the sine wave so what we need to do is we need to multiply this by two times ma pi as we do that then this will be a random value between 0 and 2 pi that we can add to initial thetas i'm going to add this random target okay and then what we need to do now is now the calculation of the amplitude is not going to be the same for all the leds it's going to be different for each one of the leds so i'm going to have to take this and move this inside of and i'm going to move this into inside of the for loop that is taking into consideration each one of the leds and you can see that to this angle to the angle theta what i'm going to have to do is i'm going to need to also add that initial offset that i generated for each one of them so i'm going to have to add init theta of of i okay so that is going to be the initial random angle with which each one of these of this um [Music] each one of these led lights started okay beautiful okay so if i do that then i get something here and then oops oops sorry whatever i do i'm going to plug this in here and it looks like i'm getting something so i got it i got random initial values and then if i press play you can see how i don't know if you can notice but they are slightly changing let me change the the let me change this and make it shorter okay so we're going to oh i'm not sure that this is changing actually i'm not really sure that this is changing well let's see here we don't have to speculate this one goes from [Music] zero it goes to zero and then this one is maxing out and this one is going all the way up so it is working it's just that it's very painfully slow okay but it is it is actually working so maybe we can speed it up and we can say 30 frames per sec oh wait so i changed the wrong one oh yeah yeah sorry sorry sorry i changed the wrong one that's 10 so 30 frames per second in two seconds okay and then all righty that's much better so you can see how each one of them is pulsing at its own pace all right so let me put this back at 60 and put it back at 10. yes just very slow nah so we're gonna do five seconds for this one okay or maybe even less three seconds okay we like three seconds for this one so that the three pulses beautiful alrighty so now we have lights pulsing at the same rate at different rates and what about if we actually have them posed with a slight offset from each other okay what does that mean what i mean with a slight offset is that if instead of just randomly starting from whatever and then getting like a curve here another curve here another curve here that looks kind of um if what i do is the initial values are actually all in sequence and then because all the led lights that go from 0 to 500 they're all actually very physically close to each other if what i do is instead of giving them random values between them what i do is that i give them random offsets that are very close to each other from one another from a mathematical standpoint what i would like what i would end up getting is a curve that looks like this another curve that looks like this another card that looks like this so i would get like a much more homogeneous distribution if you will but in the physical space what i will end up getting is i would end up adding a sequence of blinking that kind of follows the trajectory of the led cable that is wrapped around the tree so this is just as simple as creating a sequence where the initial values are not random but they are simply a slight offset from one to the other what that looks like is let me create let me copy and paste this and then i'm going to call this poles with an offset all right and then this one is going to be called pulse with an offset and then here in the original here instead of creating these numbers with a randomization with an with a slight offset initial angles what i can do is i can say i'm going to create a value here but this value instead of being random what is going to be is going to be starting from zero and it's going to be the full cycle so 2 pi divided by the amount of leds that i have and then multiplied by where this led is on the sequence of these leds so that's going to look something like uh 2 times mass pi divided by the amount of leds that i have all right so divided by led count so that would be so that would be how much angle in signed terms there is between each one of them and then multiplied by the position of this end of this led inside of the sequence of leds if i do that just as simple as that if i do that what i'm going to get is a distribution that is going to look much more sensitive to where those leds are in three-dimensional space so if you can see now if i run this because because you can see that how all these led lights which are in sequence they start turning on more in a gradual way right and then they go down the tree and vice versa which is kind of super nice right and this is because again the position of these elements in three-dimensional space is based on a calibration routine that uh my students and i work together and that is kind of working in this little bit of polishing but it's kind of there so it gets a very nice spatial effect all right beautiful can we add some color to all this stuff the way we're going to add color is that i'm going to take the sequence that was a random pulse so this one and i'm going to duplicate it here i'm going to be based off from this one but what i would like to do now is i would like to maintain this random spirit of the pulsing so i'm going to keep random but then i'm going to divide all the led lights in two groups one that is going to be red lights and another one that is going to be green lights because you know it's christmas lights so and then each one of them is going to pulse at its own rate but it's going to be rendered with a different color so paul's random color i'm i'm going to save that here all right and then i'm going to get into the code and then what i would like to do here now is that just like i created a list with 500 numbers that represented the random offset that each one of these leds start with what i would also like to do is i would like to create a list with 500 boolean values each one of them representing whether if the led is going to be red and whether it is going to be green and then randomly assign values to the beginning of that so i'm going to start generate random distribution of colors so what's that going to look like i'm going to create a list of boolean values and i'm going to call that is is red all right that's going to be a new list of boolean values and then for each one of the leds i'm going to copy this for loop here for each one of the leds what i'm going to do is i'm going to create a random number between 0 and 1. and if the value of is 0 then is red is going to be true and if the value is 1 it's going to be false all right so how am i going to do that well i'm going to say integer random integer is going to be equal to the random generator that i have and a next value that is going to be from 0 to 2. and remember i'm using 2 because i know this guarantee that the result will never be the maximum value it can be the minimum value but it will not be the maximum value so if i want a 50 distribution between results 0 and results 1 then this has to be the value of 2. and then here what i can say to the value of is red i'm going to add what am i going to add is our i is this equal to zero then i'm going to add the value of false otherwise i'm going to add the value of true this is a ternary ternary i don't know how to pronounce that ternary conditional uh i believe i have a video somewhere explaining that so there might be a card popping somewhere here or there if you're not familiar with this anyway so with this now i have a list of 500 booleans trues or false which i'm going to use to decide whether if the light should be red or blue all right here the calculations for the brightness are going to remain the same i get a value of brightness but then here what i'm going to do is i'm going to say choose red or green so i'm going to say if is red for this led light that i'm in right now if this is true then the values for r should be brightness and then the value of green should be zero and the value of blue should be zero that's one thing otherwise if i don't then uh this if it's red is not true then brightness should be here and red should be here correct let's try that out so i'm going to run this and i can see some values here i'm going to plug this are you ready for this are you ready for this what are you ready for this and i'm plugging a plug it here and whoa why no what happened oh no i have to plug it in here sorry oh oopsies okay so i'm going to have to redo this so it goes in here and this is the one that goes here and then etc and then you can see that it's pulsing painfully slowly let me speed this up a little bit um so i'm going to do the value of two and then i'm going okay so you can see how now the tree is pulsing between reds blacks and greens all right it's very christmasy i kind of like it i have to say though i was running this yesterday uh in the in the tree and my partner who's a minimalist like me she was like no i don't know about this we're gonna have to keep it in the white domain huh our christmas tree is very minimal this year okay all right beautiful what are we going to do next now oh boy i've been this video is gonna get super long should i break this up into two videos should i break this up into two videos all right okay i'm gonna let me think about that yeah it's getting late ah it's getting a little late and i need to and i still want to cover more stuff so i think i'm going to stop the video here and i'm going to continue i'm going to continue tomorrow or friday or whenever i can um yes yeah because the rest of the ones that i want to touch upon are actually they they rely on the spatial quality of the tree so that's going to take a bit more computation so i'm going to do a three part video in this case yes so i'm going to split it here then okay all righty so i'm going to stop the video then i'm going to wrap it up um i'm going to wrap it up and then i'm going to record the introduction for this video okay and i believe that at this point the thing that we're going to do is we're going to move on to the next video because i think this one has gotten pretty uh big at this point and um and i'm kind of i kind of like that all the sequences that we did here were um sequences that didn't really need in a way to know where the leds were in three-dimensional space they were just playing with random values with positions with the sequence of where the leds are one after the other but not in spatial terms and i have a few other examples that i would like to run on that actually rely on knowing and playing with where the leds are in three-dimensional space so i think i'm just going to move all of those examples to the next video and and i will also show case those examples executed on the tree in the last video all right um so or maybe not or maybe i just do one video just for that okay okay so let's so then i'm going to wrap up this video thank you very much for being there thank you very much for sitting down to this whole thing i hope you found this exciting and fun i'm dying to show you how these things look on the christmas tree okay which will happen very very soon all right so in the meantime if you thought this was cool or fun or whatever you may wanna like this video subscribe to the channel leave a comment join this board send us a coffee i don't know whatever that looks like for you all right so thank you very much and see you in the next video where i will do more examples that are actually aware of the location of these elements in three-dimensional space thank you bye bye okay [Music] all right let me add a few so i'm going to okay so let me record the introduction then oh and let me add matt's video at parker christmas stream okay okay hello this is jose whiskey starting over again and starting over again of course i need this right of course what am i thinking of hello hello merry christmas season how's everyone doing this is jose luis here at parametric camp and welcome to the second video in this mini series where we are creating parametric tools and computational tools to illuminate a christmas tree that has been wrapped with a string of 500 led lights that can be individually addressable and controlled in their rgb colors i'm going to take this because it's gonna it's gonna fall it's gonna break can you see how this is this was green so in the previous video in this series i showed you how to create a simulation framework so taking the coordinates of taking the coordinates of the points from a file and taking some animations that have been generated as a csv file and do some some and do some custom rendering with grasshopper in this video i would actually like to get hands-on into the actual generation and the design of those sequences of illuminations and generating those csv files that we will be able to then load on the christmas tree so what you can see is a few examples where for example i have generated a csv file that has absolutely nothing and that's what i'm seeing here right now that is useful for turning the led tree off and actually we will be using that a lot or for example i can generate a sequence where the tree just pulses all the led lights turn on and turn off very slowly just pulsing in unison all right that is not very exciting but it's a good segue into figuring out how these sequences can be generated we can do absolute random so we can just generate a blinky effect all together uh randomly on the christmas tree we can do that in monochrome or we can do that with color is equally easy or difficult i've actually run this in the real world and it's not very nice to watch it i'm much more into the mood of more let's say minimalistic approaches or delicate approaches where if we're going to do random let's just do it in a small soothing way i'm not sure if you can appreciate how the leds are very slowly fading in and out but at a random offset from each other but in a very soothing way i like this a lot or if you want to go more on a christmassy kind of a way you can take a look at doing this but with two sets of random colors green and red for example just for more of like a christmas flavor kind of situation and last but not least we can also have that random offset applied along the elements of the of the string of led lights because the leds are placed one after the other in a string it's very easy to know their position along the wire and therefore make the offset be slightly off along this um along this wire and therefore because all the leds are very physically close to each other on the tree it will generate this spatial effect of the light traveling up and down the tree which is very interesting this is not taking into consideration where the leds are in xyz it's just a consequence of the fact that the leds are actually very close to each other in physical space all right so the examples that i'm going to run into or that i'm going to help you develop in this in this um in this video are all just taking into consideration their position along the string of leds not yet taking into consideration their position in actual xyz space that will be the topic of the next video in this mini series all right and uh and last in this mini series i will probably have another video well i will take all the examples that we've done here and i will actually show you how they work on the physical tree all right i just want to remind everyone that these we're doing this because we were very inspired by the work of matt parker from stand-up match and the work that he did last year where he bought the tree he wrapped it with the led lights he created a computer vision routine where he was able to take snapshots and calibrate where these leds were in three-dimensional space we're living off a lot of his work his ideas and some of the code that he published and i would also like to thank my students who helped me put together the actual tree and wire the lights and do a lot of the code base for especially for the calibration that we will be seeing in further videos all right so big hands up we cut us to matt parker and to my students and i will probably post a link to this video somewhere popping up as a card here on the corner and there will also be a link somewhere on the description of this video all right okay so let's start writing down like a few led sequences um this is going to be a lot of fun hohoho all right oh i am super tired oh okay ah i am very tired right now that was a lot of christmas in a nutshell okay yes so i will do the next videos next week or whenever i can actually make that happen okay beautiful so thank you very much whoever to anyone who's there it was a pleasure as usual um i want to make this video happen sometime soon i may do it tomorrow morning or friday morning the rest of the work i'm not sure but i will hopefully i will hopefully get that get some of that done very soon okay beautiful thank you very much everyone it was a pleasure bye bye see you at some point tomorrow friday i'm not sure bye-bye you
Info
Channel: ParametricCamp
Views: 215
Rating: undefined out of 5
Keywords:
Id: Zjsj7q6eJMw
Channel Id: undefined
Length: 120min 38sec (7238 seconds)
Published: Wed Nov 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.