Houdini Algorithmic Live #094 - Sand Trail

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay hello hello so this is junction horizon and this is the weekly tutorial live for houdini this is the 94th episode the topic is to create a trail simulations on a sand like surface by running a balls on top of it to create this kind of trails and the surface itself it's not limited to a grid surface but can be any kind of given geometry such as sphere or like pig head or any kind of geometries you could imagine even with the whole open surface okay so that's my goal today to create this kind of simulations from scratch using houdini and without using any physics simulations like vellum i'm just gonna use solver with simple vex script to achieve this okay so it's not really physically correct but uh you could have a similar effect such as these and i have also set several parameters for example how much time this trail will be fading away how much it it takes to fade away these trails so if you make the flatten ratio stronger like 0.2 the speed how how how fast the trail disappears is going to be greater so you can see that as soon as it moves the ball moves the the trail just fade away given you giving you back the original surface but making this flatten ratio smaller like point zero two you'll have these trails in timeline giving you some landscape created from the time lapse okay and uh the the how ball moves is just the random stuff i'm using a noise functions to making these balls to move around freely randomly on top of the surface so it's nothing special it could be um [Music] overwritten with some something more controllable movement like using a vector field or anything but that's another topic so for this one i'm just gonna use the random movement random uh walker functions to achieve how ball moves okay so let's see how we could do this from scratch all right so i think it is easy to start with the grid surface even though we want to achieve this on any given 3d surface i think it's a bit easier to see how it works on grid a flat grid surface so let's do it from that then we could extend it to be used for more complex geometry later on okay so let's create a grid and since what i want to do is to move the point positions on a normal direction in this case a y direction up and down by the existence of the balls if the ball is close enough to the vertices or points then we want to push down these points based on the radius of the ball okay so more points we have on the grid more high-res simulations we could create so let's make the number of rows and columns bigger enough big enough to create a smooth surface same as curvy surface so let's say 150 or 150 and let's also create a normal function i mean normal node to create the point normal which we could use this later to achieve in to use it to determine in which direction the ball should move or uh to create the rotational axis for the ball rotation and so on so the normal information is important i think okay and the next thing i want i would like to create is the rest positions since we are going to move the point positions of this grid up and down based on the ball positions the ball existence we still want to make this back to the original positions by the time using time scale so let's say if the ball goes away from one point to another then by setting the time scale time step how much time it takes to make the pushed surface goes back to the original surface we in order to do that we need to know the original position of the surface so this is going to create the original position of the grid by creating the copy of point position to as a rest attribute rest vector attribute so later on we're going to use this one to get the original surface point positions for many purposes the one one of the purposes to be a goal point positions for the surface to go back to the original positions okay so what else um let's also create a group to each of the point just in case let's create the point group called surface all right so i think this is enough for the preparation for the original uh surface to move the balls around now next thing i would like to create is the actual ball point position the the ball positions which is going to move around on top of the surface so let's create that by first of all creating a scatter node to a surface and let's create that from this normal node so that the point created on top of the surface will have the copied normal direction like this okay which is which can be used to determine the axis for the this ball's rotation okay now that number of poles right now is a bit too much so let's make this a bit smaller like let's say 20. right and let's also create the point group to these point let's name this mover or ball any name you want i'm gonna name this mover right then let's also make this as point group okay so right now we have mover point group and the surface point group and for the ball the ball points which have the mover group i also want to give additional attributes such as the size of the ball or the initial direction the velocity of the ball in which direction should the ball go initially and also a up vec vector which is going to be used to determine in which direction the ball is being copied or a ball being directed okay so for the initial velocity i could just use a point wrangle and let's say init initialize okay so first of all the initial direction could be [Music] random so let's how do i call this [Music] i'm gonna call the name for the direction to be move direction equals to random created from the point positions and since random will create a vector value for x y and z coordinate from zero to one we want to have a negative value as well so let's subtract this by 0.5 as well so that will have a value in between minus 0.5 2.5 for all x y and z okay now in this case we do have a y value applied created by using this calculation so if you just copy if you just visualize this move direction [Music] attribute you'll have a direction which goes up or down direction as well which is not on top of the surface which is a bit problematic because we don't want to move the walls like to the air or to the ground so we need to constraint how the ball moves so that it will always move only on top of the surface so we need to project this vector on top of the original surface this one so let's see how we do this how in order to do that we need to know the normal direction of the surface the closest normal direction of the surface then use it to use it use it to determine the plane the x y i mean the plane for the surface from that normal direction then project the vector value to that plane which isn't that hard to do but we we do need a little bit of vector calculations to do that so first of all in order to retrieve the closest normal direction from the surface we could first connect the surface information to the second input of this initialized node so for example for this ball point we want to get the closest point from the surface such as this point and get the normal direction which in this case is always facing upwards so we know that it's 0 1 0 but in case we are connecting the more curved surface like sphere or anything we don't really know what the normal direction is so we want to in order to make it procedural we want to re we want we always want to retrieve it through this surface informations not by hard coding so let's get that in order to get that we can say norm is equal to first of all we need to get the closest point from the second input using the current point position which then we could get the normal direction from that point on a surface then we could um create a axis informations from this now in order to create an axis informations we need to kind of get the um x and y axis on top of the surface or we could also say u and v direction for the surface and we could calculate that from this normal but um there is an easy way much easier way to do that maybe we don't really need to use the normal directly as it is but after instead of using the normal direction we could probably use polyframe which will give you two informations one is normal and one is a tangent u value which will give you a normal direction to a point attribute but at the same time it could also give you a tangent vector value which lays on top of the surface we don't really know in which direction this tangent you will face to or direct to especially when it comes to a grid where the direction is not really specific but we don't really need to care about in which direction the is tangent u is facing as long as we have at least one direction then we could assume it as an x axis on top of the surface then if we rotate that angle by 90 degrees using normal as an axis rotational axis then we could also get the y direction on the surface then if we have x-axis and y-axis then we could we have enough information to project any uh three-dimensional vectors to it so it's visualize this tangent u vector see in which direction is facing to let's make it red and as you can see it is facing on top of the surface it is directing to some direction which is aligning to the surface so this is good right it is right now directing to direct diagonal direction but it doesn't really matter in which direction it directs as long as it's aligning on top of the surface okay so let's reconnect it instead of the normal then going back to the initialize we now want to get additional vector value which is tangent u or we could s directly say x axis the actual attribute that we want to get is the tangent here okay now in order to calculate the y-axis value um we want to rotate this using this normal as an axis so let's do that by first of all rotating the matrix identity matrix by 90 degrees using normal as an axis then create y-axis or we could just calculate the cross vector between x-axis and normal which might be easier yeah i guess that's much easier anyway either way is fine just i've just created the x and y axis like this and then we then could use this uh two axis value which is aligning up on top of the surface perpendicularly to project this moving direction which is currently directing randomly on 3d uh space you can do that by like this vector or move direction is equal to vegetable multiply x axis by the dot product of the moving direction and x-axis plus y-axis multiply dot b by axis like this and then we can see that this yellow angle has been projected on top of the grid on top of the surface like this so what is doing here is that using dot product between the current original moving direction and the x-axis you have given the lengths how much it will cost to go to the x-axis for this moving direction and in this case for this y-axis you can now calculate how much it goes to the y-axis by calculating the dot products so by adding two direction as well as multiplying these two moving values you'll be able to get the final projected vector value projected on on to the surface and this is this technique technique is going to be used in other places well in this case in this project so remember that remember how you could do this it's pretty handy vector calculation okay now that i got this moving direction i also want to normalize this and set a initial speed so that every balls moves to this specific direction in the same speed initially which might not be necessary but it's up to you i'm going to name this init move or in it speed which is going to be used as initial speed how much it travels from this point to the yellow direction let's say 0.1 so initially the ball will move to this yellow direction by 0.1 as an amount as an initial speed okay so that's the initial setup for the for the movement for the speed and i have just created this attribute value called move direction let's also create an attribute for the size for this ball and in order to specify the size i'm going to set the p scale attribute which can be used with a node like copy to node so p scale is equal to again i'm gonna use some random function to randomly set the scale this time let's use ptnum doesn't really make a difference if you use point position or pt number but if you want to dynamically change the scale then might be better using pt num especially if you want to change the scales inside the solver and you want to keep the random size somehow or at random seed value because pt num won't change through time scale but the point position will change through time so that's the difference but in this case we are not inside the solver yet so using pt num or point position doesn't make any difference okay so the result in this case will give you a value in between zero to one but i want to control the minimum and maximum for the ball size so let's create the fit function let's create some parameter like min scale or let's say min radius and max radius for the ball so from point one to say one will be the size for the ball and let's check how big is that using copy two note copy two points i'm going to create some balls to rotate and the radius should be equal to 1 but in this case what i've just created has the radius equal to 0.5 so let's make this one and then connect to a copy to point to see how big is all those points or balls which looks pretty big too dense so let's make the number of points a bit smaller like 10 balls okay so let me also check the radius or the p scale so it is in between 0 to 1 0.1 to 1 and the original sphere radius is also equal to one so should be every ball's radius should be in between point one to one which in this case the diameter is in between point two two two but what we're going to use is the radius to use it for many like collision and so on on the solver okay so we are ready with the balls as well but we don't want to use this ball inside the solver yet we want to you we just want to use these points inside the solver to move around then after we have calculated all the simulations in solver we could then copy these balls to a points that's my goal so let's create a solver since we have two types of geometry or two types of information one is the surface which we want to move the points or balls on top of it and actual point position for the balls to move around so let's merge these two informations together and connect it to a solver okay and let me let me check if we have enough informations for this point i think i'm missing something here yeah okay i realized that uh what i what i am missing is the up vector uh to in order to be used with this copy two points the up vector is needed or necessary in order to determine the rotational movement in order to create a rotational movement to a sphere uh if you look at the examples that i have you can see that if i play it the ball is rotating not just sliding but it's rotating i want to create this kind of effect so in order to do that you do need to you need to control both normal normal direction to the to the ball points as well as the up vector value to the points by controlling these two uh vector informations to the ball points you'll be able to create this kind of a rotational movement okay so that's the reason and to do that actually we could just copy this tangent u value that i have been created on the surface which can be used as a up vector to this point uh a ballpoint current ballpoint have already a normal direction so what we need oh actually we do have a tangent to copy to the ballpoint so we could just copy this tangent u as an up vector so just do like this v for up vector is tangent u and that's it yeah should do it and anything else i don't think we need to do anything else anymore as initial initializations i think we are ready to actually calculate the trail inside solver so let's go inside and let's see where we need to start off first of all um we actually need to in order to create the trail we do need to make those point move around those ball points to move around on top of the surface so let's create that part first first of all i am going to split the two informations that we have one is the bowl which have the mover group and one has the surface and let's connect it with the null node i'm gonna name this ball i'm gonna name this surf okay i think i'm missing the surface okay here it is so the first thing i want to do is to move this ball point positions randomly and the way to move this is not really important here i mean anyway is fine i think what i'm going to do is to just create some random value to move these point around points on top of surface okay and i'm going to use the point wrangle to actually move the point i just i don't just want to move the ball like by sliding to the direction but at the same time i want to rotate the ball to make it look like we are seeing the balls being rotated on top of the surface case which could be used with the textured bowl all right might be should be interesting so let's do this um my plan here in order to how i am going to move the ball is to use a random or noise vectors as a accelerational vector value to add it on each time step then also constrain the maximum velocity by some value then based on those velocity we want to dynamically let those balls move around on top of the surface and when it reaches to the border of the surface i want it to bounce to the bouncer to the uh opposite direction as well as if when it touches the other balls i also want it to bounce it back to the to the opposite direction so we do need to create two types of collisions one for the border one for the other to the other balls we also need to make the random walker functions let's first bike let's start by creating a random walker functions first of all creating a acceleration random accelerations based on the noise okay so to do that let's you let's try to create the directional value by either using noise or cool noise i will try to use curl noise in this case but let's see if it didn't really work well i'm gonna switch it back to something else now in order to use the coil noise we need to have a seed value which it has to be vector 3 through your vector4 i'm going to create a vector let's see let me check the documentation page so we want to go back to the effects nope we want to check the effects functions look for it a name called curl noise okay so we have vector seed or vector 4 seed right now we are working on on 2d surface so using vector it should be fine by giving x and y as a x and y positions or x c and positions and for the z value for the seed we could use a additional time value but that's only for the flat plane if when it becomes more three dimensional geometry like three sphere think we should use the lighter one the latter one vector four using xyz for the positions and t for a frame value so even though we are right now working with the flat plane i'm gonna use this seed instead all right so vector for seed is equal to first of all a point position x plane position y one position z and for the rest value frame all right now although this is pretty much okay uh i think the speed the smoothness or the speed is a bit too fast i mean gives you two randomist values in this case we wanna reduce the the distance between the point position to create a more smoother movement value in order to do that we need to multiply each of those coordinate with some valid constant value so let's create that uh how do i call this versatile smoothness so let's call this f s and the smoothness can be multiplied to a both x and y and z for the frame we are going to multiply with another value like uh speed so let's call this p okay and we also want to differentiate the value between different point numbers so we could add additional point number value with really high value to differentiate the volume between different point numbers okay this should give you some smooth random values to each of the point and let's check that out uh we could ju we have just created this direction let's try to visualize it and see how it moves show up direction as a marker okay and if i play this okay nothing happens i think i am missing something which is the smooth value and speed so let's make this um 0.1 and 0.1 see the difference right by changing the speed you see how fast those direction changes the smoothness doesn't really matter in this case yet because it's not moving yet this is only available when point starts to move around so i'm gonna start with point one for this moves and for the speed i think the one that i'm seeing right now looks good so how about .05 yeah good enough i think so let's use this as a uh value for the acceleration now we have created this base vector value for the accelerations but as we can see this vector is not aligned on top of the surface so what we need to do now is to align back again to the surface so that meaning we need to project this direction to a surface so that the the actual moving direction of the ball is on top of the surface okay so to do that we what we need to do is to go back and copy what we have done inside this initialized value which is somewhere around here this is how we have rejected the vector value or we could create it as a function so that we it's much easier to reuse it so let's create a function function vector project vector so the actual vector that we want to project let's call this v and that the additional information we need to have is the x-axis and we also want to know the normal direction so by having those three informations we will be able to get the projected vector value because we can calculate the y-axis by using normal direction as well as this x-axis okay so i'm going to copy some of those stuff first of all create the rotational matrix as an identity matrix then rotate that with the normal axis vector value then create a y-axis by rotating the x-axis input by 90 degree then we could create this vector value let's not name this rod v is equal to x axis by a vector value that we want to project which is this one and this is the result that we have got and that is the one that we want to return okay so by creating these kind of functions it's much easier for us to reuse it in many places just by copying this function over to another wrangles or we could also save this as a dot h script file externally and import it back to houdini from anywhere now i won't do that but i just going to copy and paste this functions okay so we can then remove these these and calculate the uh b by calling project vector which we want to project this moving direction with x-axis and and replace this with rot b will give you the same result okay and this is what we want to use inside the solver as well okay going back and let's copy that function up above and let's call this alt to project this direction that i've created shall we okay so in order to do that first of all we need to know the closest normal direction a closest normal direction of the surface so we still need to refer to a original surface which is which can be retrieved from this first input which never changes over time you'll always get this original surface but we need to we want to split this to get only the surface value okay and this is what we want to use let's shall we name this so that it's easier to understand what this is so this is the init surf and init ball now i don't think we're going to use this init ball we're only going to use this in its surface which are not going to move over time which can be used as a reference to retrieve the information we need in this case we want to retrieve the normal direction and the tangential vector value all right so first of all let's get the closest point number from the second input just like we did previously and let's get the normal direction and the tangential vector value named as x-axis just like we did last time then we could calculate the projected vector value to a surface vector projected position is equal to or projected direction so p direction is project vector a direction norm x wait a minute uh no x axis and norm all right and let's check this out right now you can see that the vector has been projected on top of the xy surface looks good okay now now that the vector has been uh projected what we want to do now is to [Music] use this projected directional vector as a acceleration value the acceleration value acceleration vector should be added to the current velocity and the current velocity is named as moving direction move direction okay so we're going to create a velocity by adding the moving the current velocity which is named as moving direction plus projected direction as an oscillation volume okay and this newly created velocity value is going to be used to move the ball toward this direction although by adding acceleration value for each time frame there is a chance that the speed going to be too fast at some point so we need to limit the maximum speed of this velocity at some value so let's also do that by limiting the lengths the size of this vector value this velocity vector value to do that we i'm not sure if there's a way to [Music] limit the size or amplify the size of the vector value let's see if not we'll do it a bit harder way close to a normalized probably we might be able to use minimum maybe not yeah i don't i don't know if there's any functions to do that so i'm just gonna go like this first of all create a normalized velocity which will give you a length of 1 to this for this velocity then multiply by the lengths of this velocity which will give you the same result the original result but what you want to do is to limit this links by specific value which is going to be called as maximum speed how much ball could move as a maximum speed and let's set this to 0.2 for now so that when the length of the velocity goes over 0.2 then it will be limited to 0.2 by using this minimum function so that it will will always stay at point speed of 0.2 no more than that it could go to more than less than 0.2 like close to zero it's fine but going over 0.2 is not permitted in this case okay so that's for the velocity and we are going to actually create the updated point position to move the current point by adding the velocity to this current point position all right and let's see let's visualize how it moved okay we are going to hide this and instead we're going to show up the move direction okay so i'm going to comment this out and see how the point has been moved so previously the point has been here then the point has been moved to this direction now i think it look i think it moved to a different direction by this yellow but the yellow uh moving direction has actually been overwritten by this velocity so we actually need to override this moving direction as well with this velocity now we see that the point is moving to to this direction okay now that looks good and let's see how it animate how it creates the animation by trying to simulate the point at this point okay so the ball is moving randomly on a plane that is fine but act not on top of the surface it goes off the surface as you can see so the next thing we want to do is to limit these bowls to move around only on top of the surface all right in order to do that we could calculate the distance between the point on the surface and if the distance is close to zero then we know that the point is on top of the surface if it goes over zero then we know that the dist if the distance is more than zero then we know that the point is off the surface so that's one way to determine if the point is on or off the surface and if it's off then we want the point to go to the other direction to go back inside the surface okay so that's what i want to create as a boundary function so in order to do that we know that this t pos that i've created the default vector variable is the updated point position what you want to do is to check if this point position update did point position the ball up to the point position is actually inside or outside the plane by checking the minimum distance okay so that's what i want to do next all right so to do that we need to access to the initial surface geometry which i have already connected to the second input this one so what we what i just need to do is to calculate the distance between the point the updated point position and the surface and see if the value is close to zero or not right let's do that and to do that i'm going to use the function called xyz distance and to use this we need two parameters one is the primitive number and one is the uv and calculate the distance the initial surface and the update point position as well as giving you the primitive and the tuv right now if the distance is close enough to zero then we know that the point is on top of the surface it's not if not then we know that the point is outside the surface so we want to create the opposite directional vector value so let's create that kind of conditions here first of all if the distance is small enough or big enough let's say it's big enough by some value some checking value then we want to create the opposite direction value for this moving direction now in order to determine how much values we need to input here like is it okay with zero or zero zero one i think we could use this speed as a guide since for each frame we are adding 0.05 an excellation value to a moving direction i think [Music] we could use this as a guide to determine the minimum stepping value or checking value so we are going to refer this which is called p here uh wait a minute do we use this as a acceleration value maybe not actually we do need to i think we do need to add exhalation um because this speed is only used for the noise and it's not really related to how fast the added acceleration is in order to control how fast that edit acceleration is we need to add apply additional multiplication to this p direction like this acceleration speed so this is where we could determine how much speed is being added each time by each frame to a specific direction and we this is this value could actually be used to determine the threshold to check the border if it has go off the border or not so i'm going to copy this acc speed and multiply by some smaller value but like 0.5 i'm not sure what would be the best value for this one if it didn't really work then we can control this threshold value later but right now let's go with acceleration speed multiply by 0.5 to make it small enough to check small enough value to check if the point is go outside or not all right so so if the distance is more than this value we are saying that the point went outside so in those cases we want to create the opposite directional value for this moving direction which is this one so let's do that and in order to do that in order to do that i think in this case we i need to write some sketch to clear my mind how i'm going to do that because it you do need to do a little bit of vector calculations for this which is a might be a bit complex i don't know let's see so let's say this is a border and the ball is moving like this and when the ball goes outside like this it's a bit hard to let's say the ball is going like this way and when the ball goes outside when the this point is outside the surface meaning the distance is larger than the threshold we want to balance it or in this case move this ball to the opposite direction instead so meaning we need to reflect this vector value to this direction somehow and to do that first we are we can assume that there is a um some mirror plane like this then reflect this vector value by using this mirror plane to create an opposite direction okay and to do this to do this um we need to do some vector calculations for this and the way that i'm going to calculate this is similar to what i have done with the projection uh so first of all what i need as an information is this axis direction and let's call this x-axis or let's just call this capital x okay and another directional value that i need is where i access the value that i need is this direction which is horizontal to the border which is the y axis now the only thing that i need now is to project this original directional value to this x and y so in this case if i project this vector value to x and y what we got is b y and bx right and previously when we were projecting the vector from a 3d space to a 2d uh plane we are we were just adding v x and v y okay to create the v on top of the projected plane but if we want to reflect like this then what we could do is to in this case if this is the x-axis we can what we need is actually a direction in this direction is it no sorry but uh in this direction oh wait wait wait uh it's a bit confusing is it the actual directional actual direction that i want is this direction instead of this okay so this can be retrieved by adding b y as it is but adding negative b x because as you can see it's going to the negative direction so b y minus b x will give you a reflected vector value in this case and that's it you'll be able to get the reflected vector value using this equation easy as that let's see how we do this okay so in order to do this uh just like we were doing with the projection we could create another function to do the reflection and to do this we need a axis x-axis as well as the normal direction in this case x-axis on y-axis i guess what we need or wait i guess it could pretty much the same like this let me think let me think what kind of parameter we need so we do need this we do need this perpendicular direction [Music] which is this x-axis which can be retrieved by projecting this point to this edge okay that's one thing and another [Music] in order to create this y-axis we can calculate the cross product between the x and the normal so yeah we still need to know the normal direction so i guess develop the value that we need is pretty much the same as the projection vector we're going to change name to reflect okay and okay instead of using matrix rotation i'm going to use cross vector cross product instead which will give you the same result i think it doesn't really matter if you use rotational matrix or cross product it's i think it will just give you the same result to calculate the y-axis it's just based on your preference i guess so in between the x axis and normal and let's make sure that this is normalized use it as an axis vector value all right so these three lines has been are written like this which will give you pretty much the same result so yeah one line maybe is much better okay now um yeah reflection vector can be retrieved by adding x-axis to a negative direction and using y-axis as it is and that's it that i think that should do the job as a result you get a reflective reflected vector value let's check so in order to get the x-axis we need to project the point to a border and we don't really have the border informations in this case so let's create that by first of all remove all the interior edges using divide node and using poly path node to get the outline of the surface and connect it to a third input now we can have this edges and we are it's easy for us to create the projected point position then we can also calculate the projection vector although there is a chance that we don't really get this border lines when it becomes a solid objects being inputted in those cases we need to skip the [Music] collision detection so that's what we need to remember but as long as there is a border we could do the collision check so let's do that so in order to do that we are going to use another x y z distance let's call this b dist to the third input and using the current point position give you to result one is be prim one is bub that and a you if you couldn't find any result then the b prime will become negative so let's make a conditions that we are only going to calculate the collision only if the b prime is equal or more than zero all right then this value should give you some information but what actually i need is this bu v value in order to determine the projected point position on top of the border so b plus is equal to prem u v we want to get the projectile point position at b prime b v okay then we could calculate the x axis at this point x axis by subtracting b position by current point position which will which should give you the vertically projected direction which is similar to this x-axis and let's also normalize this right and what else we also want to get the normal directional from the surface to calculate the y-axis meaning this one so let's get the normal function now normal surface normal direction from the surface which can be retrieved i think we have already got it somewhere which is this one yeah so let's copy this one or we could just use it as it is so we are ready to feed this b position i mean no i mean x axis and the normal direction to this reflecting vector function let's use that ref vector value is reflect vector the one that we want to reflect is the this velocity so velocity x-axis and hopefully this will give you a reflection vector value and seems like we are using this x6 x axis somewhere else let's use a different name bx-axis right so hopefully this reflection vector will be the reflected velocity value now what we want to do is to update the velocity with this reflection vector value okay and and hopefully this will give you the the final vector value to move the point so instead of updating the point position to the temporal point position i'm going to add it by velocity direction directly to see how it goes okay let's also show up the surface and see how the point moves okay you can see that now the point is bouncing around the surface at the border looks good the ball is a little bit moving too fast but let's say it's fine for now now we want to check this if this could work on three dimensional surface so let's go back and create a switch node to the initial position where we are placing grid place some three-dimensional geometry like sphere let's make it polygon and let's make this big enough like that high-res enough like that switch to a sphere and what i want to check is if this code still works on three dimension hopefully it does if i play it and as you can see now it goes off the surface that is because there are no restrictions for the point to stay on the surface right now so what we need is an actual uh additional constraints with so that the point will be restricted to run on only on top of the surface okay so to do that we are going to add additional ray node to a point as a minimum distance to a original surface okay by using this i hope the point will stay on top of the sphere all right and let's stop at some point and check the velocity and seems like the velocity is not really aligning to a sphere let's see why that is okay which is being calculated somewhere around here and this one should have created the projected vector value which seems like it's not right now so let's see why okay well actually what we needed to project is not only this one not only this uh additional vector value but the final velocity as well yeah i think so right after i have added this projected vector to the velocity we also needed to project this one to a three-dimensional surface meaning i need to do another project vector x-axis like that and will give you a better result if we look at one of the points it's moving on top of the surface as it should all right looks good okay now right now this is the solid geometry so it doesn't have any balancing effect so let's try with the 3d geometry which has some holes which has some um open geometry shall we okay i have a question main pause wouldn't work um i think i remember that minimum position didn't really work for the edges it might have but um what's good by using xyz dist is that we could also check if there is a primitive available or not so we could create additional conditions here i think minimum position doesn't give you that kind of information if we couldn't if you couldn't find any information it will just give you value 0 or some other value so because it gives you additional information might be useful in this case all right so where are we we need to create some geometry 3d geometry that has some holes so let's do that um i'm gonna try with some simple geometry like platonic shape make it big enough and create some holes to it by deleting some of the surface by selecting some of the surfaces okay like that and let's smooth it out using something like subdivide with the open soft div by loop make it small enough okay should have enough points so what we what i want as a result is to bounce so the ball bounce at the edge at this border so that the ball always run on top of the surface let's check if this is going to work all right let's see we can't really see where the point is it's hard to see okay now i think we are seeing some cash here okay and show up the surface and see if the points bounce maybe the speed is a bit too fast i'm going to limit the speed maximum speed to 0.1 and limit the acceleration speed to 0.03 okay so we need to find out where it touches the border okay here we go so here we have this point it's a bit hard to see what that is let's make the point scale a bit bigger okay so here it is um if i play it you can see the point has bounced on a border even on top of the 3d surface so looks good i think it is working the boundary condition is working never goes off the surface and it always bounces on the border all right so the collision looks good uh collision between balls we i'm gonna skip it to the next step but instead the next thing i'm gonna try out is how to actually create the trail for the sand surface okay because i'm currently pretty much satisfied how the move ball moves i think it's time to actually check how we're going to modify the surface itself which is this one okay and to check that we're going to go back to the flat plane because it's easier to check okay and let's see how i do this right so um i am going to create a point wrangle and name this sand trail which is going to be the main vex script for today all right and i'm also going to merge the all these back together to make it as a final output value all right so let's see how we do this okay so for for each point on top of the surface we want to check we want to check for the nearby ball point position and the search radius could be the maximum radius of the ball okay so in this case the maximum radius of the ball is determined somewhere at here initialize which is one point zero so i'm going to copy this value go inside solver and have that value to check if there are any balls within the radius of this maximum radius from each of the point on the surface and if there is any we are going to calculate the distance between the point and the ball and if it's close enough we're going to dig the surface really deep if it's a bit far then we're going to make the the depths of the digging a little bit steeper okay and how much we dig the surface can be calculated by some wave function like cosine or trigonometry like cosine or sine so the goal what i would like to do is to call do some calculations so let's say there is a ball somewhere top of the surface and you calculate the distance you pick each of the point on the surface and if the point and the distance between the surface and the ball is more than maximum radius and this could be a radius which is less than maximum radius so if the distance is more than maximum radius then these points will not be affected by any balls meaning the depths won't change although if the point is within the maximum radius there is a chance that this surface point is inside some of the ball so in those cases we want to move this point downward and move create a digging hole something like that okay so by drawing this um sketch i realized that actually the distance has to be maximum radius multiplied by two in order to determine whether we should dig the whole or not if it's only multiplied by one if it's the equal to maximum radius then we can only create the holes from here which will just create some straight hole which doesn't really look natural so if we want to create some natural holes like these i guess we need to have a maximum radius multiplied by two as a threshold to calculate the distance okay that's what we need to remember for now and if we so actually those surface points are the one that we need to uh move based on this distance value so we could somehow change this distance value to a um height value how much it goes down to the negative normal direction if it's the normal direction so this is the negative normal direction by h so somehow we need to remap this to an h value and the d is the distance is in between 0 to maximum radius multiply by two okay so what i think i could do is to remap this to a angle value for the trigonometry such as from 0 to pi which means 0 to 180 degrees and if we use it with a cosine value then the value is going to be in between minus one to one with the curve something looking like this minus one to one okay based on the angle zero and go to 180 degrees okay so with this curve we could i think we could create some section of this hole by directly converting this value to a height value so remapping the value between -1 to 1 to 0 to maximum radius or the current radius will give you a shape like this i think that's my plan and let's see how we could do that um okay so as i said first thing first we need to calculate the distance between each of the points the closest we need to check whether if there is any uh balls within the search radius and the search radius is the maximum radius multiplied by two so i'm going to use npts near points function to the ball points and currently we don't have up all points the ball point and updated ball points is going to be this one so let's connect this to a second input and let's check that out now i don't want to use the current surface point position because the current surface point position actually moves around up and down to the normal direction so instead i'm going to use the rest attribute that i have created previously which never moves but gives you the original point position of the surface and that is the point position that i want to use to check the distance between the balls and we also need to determine the search radius so that is going to be maximum radius multiplied by two just like i said okay and this has to be array all right so let's loop through all the points that have been found out and let's also get the point position so that we can calculate the distance okay let's calculate the distance between the current point position and the position of the balls all right now first condition um [Music] oh well we do know that the the distance is less than maximum radius at this point because we have used this new points using maximum radius by multiply by two as uh conditions but each ball has different radius actually and we can get that information by accessing to a p scale attribute which is actually a radius for each ball which is less than maximum radius right and that is the actual value we want to use as a condition to calculate the actual moving height in this case h right so we're going to give additional conditions here if the distance is less than this radius multiplied by two only then we could move the point to a negative normal direction right now at this point we can now convert this distance value to an angle from zero to pi just like this so let's do that and is a fit current distance which is in between 0 to radius multiplied by 2 2 0 2 pi okay so we have i have just changed remap this distance value to an angle value which is in between 0 to pi now i can calculate a trigonometry value by using cosine with this angle which will give you a value between -1 to positive one i want then remap it between zero to the actual height value which should be the radius of the ball okay and this value itself is going to be the value that we want to move the point to a negative normal direction all right so let's see and we although there is a chance that the surface has already been moved by some past balls or bigger balls nearby so we don't want to override the h value the height value if the depth is uh deeper then and this value that i'm just calculating right now is uh shallower uh smaller then i don't want to use this value but instead just keep the deeper uh hole or deeper and digging value or depth so in those case we need to check if this value is deeper than the current like depth so in order to do that we need to calculate how deep is the current condition okay and to do that what i could do is check the distance between the current point positioned and the rest point position which can be calculated outside the loop so let's say depths is like this so this is the original surface point position where the surface has not been moved yet and this is the current point position when the surface has been modified using the balls which will give you a depth how much it has been by the balls at current moment then we can check the you can check we can update this steps by checking the the d pro value by using the deeper value so deps is maximum between the depths and the value that's to con that's the condition that we want to make at this point so that for each loop we're going to look for the deeper value and if the value is deeper than the current depth then update depths by the bigger value that i've created using the double position and the radius okay now after all the calculation has been done inside the loop we are ready to use this to actually move the point position to that to the negative normal direction by this length or depth and to do this we do need to know the normal direction for sure and we don't actually have that information yet so let's connect again the initial surface geometry this one to the third input and retrieve the nearby normal direction by first of all getting the nearby point then get the normal direction at this point yeah like that then we could now update the current point position by starting from the rest point position subtract by the normal direction multiplied by the depth and let's see how it goes yeah now we see some [Music] kind of a hole here being created by the size of the bowls now i haven't uh visualized the ball yet so i'm not really sure if this is correct so let's check that out by going outside the solver and place some corresponding sizing sphere to those moving points i'm gonna use another split get the mover point value copy this sphere to that point position and merge it with his surface probably recalculate the normal for that surface okay like that and i can see that it doesn't look that bad how it how the ball have created the holes doesn't really look that bad i think and if i move the ball oops what is going on here if the ball if i move the ball i can see that the ball is creating these uh trail just like i want it there is some some weird conditions happening here where ball is not really bouncing let's check why is that why that is okay it's around okay it's around here i guess it's due to a threshold value where it's checking the if the this if the point goes when outside or not in this in this case so yes we need to check change some of the value here let's see if i change this to one let's see or maybe point seven see if it changes anything nope probably smaller two five well a little bit better but not so yet maybe smaller one okay better i guess yeah well it's stuck well let's leave that for now and i can see that the trail has already been created and looks good but things that i want to do is to make the surface go back to the original position by time so that it'll you'll have more dynamic effect on to on top of the surface uh like the wind always flowing around the surface to create the surface back to the original flat surface right now everything goes kept as it is when the ball just travels around the surface so every time the ball runs on top surface it becomes complex more and more complex but by creating some flattening or smoothing functions to this you'll be able to create to a bit more dynamic effect just like you are working on top of the sand so to do this i could do it right before creating a trail using point wrangle another point wrangle and this code will going to be pretty easy i'm going to name this flatten or smoothening by lerping from the current point position to the original point position by some time value so move the point from the current point position to the rest point position by some kind of flattening ratio okay and if i make this one 0.1 you can see that slowly you'll have a flattening effect been happening to the surface but if you make it really low value like 0.01 you'll have more trail available create more like a dune like shape if you make it really big as soon as ball moves it because all the other surface becomes really flat that's also interesting i'm going to keep it keep it as 0.1 for now and see how it looks like in 3d you can see maybe a little bit smaller like .05 how's that looks good so i'm pretty satisfied with how the dune being created by the balls and how the ball moves how the ball bounces on the border now things that i'm missing right now is right now i i as you can see the ball is not colliding to each other so it just penetrates each other so that's one thing i think i can fix and also how ball moves right now the ball just slides as it is it's not really rotating like the ball should do so i also want to create a rotational like motion to these balls based on in which direction the ball is moving to okay so those are the two things that i want to apply to this uh effect or solver the ball rotation and the ball collision let's start with the ball collision shall we which is pretty similar to what we have done with the border okay so going back to the ball move point wrangle we could add another conditions to check if the ball has touched other balls okay so only if it didn't touch the border i'm going to search whether the point has been touched to other balls in order to check whether the ball has been touched to the other ball we could think like this if this is the surface as if this is the ball points and each ball has different p scale meaning it has different radius like that right and if one of the ball has the size like this and if there is uh intersections like that then we want to balance these ball to go to the other direction this one as well so we need to determine the distance between these balls two balls and each ball has its own radius radius so if radius 2 radius is less than the wait a minute if the current distance is less than the addition of two radius then that's when we want to calculate the bouncing or if reflecting uh directional vector value okay so that's what i want to do here and the way to create the reflection vector is pretty similar to what we have done to the border function that we can we can just use this function that i've created as it is okay so where are we we're going to create the condition when to [Music] add this reflection vector value so in order to do that we need we first need to search for a point position i mean we need to search for the um balls the new bibles which is in within the radius the max in this case the maximum radius multiplied by 2 i think right so let's do that so do we have the maximum radius information here no i think we need to bring that as well so float max radius and i think we were using it somewhere around here yeah this one so i'm gonna copy this value and paste it to here all right and then search for a new bibles right here if the bonding border didn't met if the bounding condition didn't met then look for the collision balls okay so searching for the nearby bowls using new points with the [Music] t pass t plus is the current the temporal position right and maximum radius multiplied by two which always give you at least one result the first result is yourself in this case because we are looking at the self geometry input so we want to skip that we only want to look for from the second value so if the length of npts is a more than or equal to 2 then we could start looking for the collision if it's equal to one then you're just looking at yourself so it doesn't means you didn't have any collisions okay look through all the points and react we can actually start from one like that and so what kind of information we need first of all we do in order to calculate the distance we need to know the point position so point p at npt all right so let's calculate the distance between the t pause and and pause all right now we need to check if this distance is within the threshold let's call the thresh and the threshold can be calculated by adding two radiuses of the sphere one from yourself and one from the nearby ball so you know that the yourself can be retrieved the radius of yourself can be retrieved by accessing to p scale but the p scale for other ball has to be retrieved using point uh function so let's call that n radius is equal to point zero p scale at npt and add it to this so this is going to be the threshold value to check and only if the current distance is smaller than this threshold then that means you the two balls are colliding to each other so that's the condition where we want to create a reflectional velocity value to be used to move moving to the opposite direction and in order to calculate the reflection vector we can use the same function here and so let's bring that up vector ref velocity is reflect vector between the velocity and we do need to know two information via axis x-axis and the normal we don't have the x-axis information yet we do have a normal function information so let's create the x-axis information in this case i'm going to name this n-axis which can be a subtraction of vector value between the nearby ball position subtract by current point position t let's normalize this and that will be the value to be used to calculate the reflection vector value and this should be it and as soon as i find it update the velocity to this reflection value all right now there is a chance that um we have like multiple collisions at one time meaning like three points has been gathered too close to each other we have two collisions at the same time in those cases we might need to do something about it we we might need to think calculate some average reflection or velocity value in those cases so [Music] let's create a value called [Music] average velocity starting from zero this could be inside this one right and each time i have calculated the reflection of velocity i can add it to the average velocity then when i went out of the loop i can calculate the average by dividing it by the lengths of npts minus one which should give you the average velocity to the opposite direction then at the end we i can now overwrite the original velocity to this one hopefully this works all right oops something went wrong okay this has to be lange okay i think npt has been used at somewhere let's change the name near pt okay so hopefully this will do the job and let's see if it will oops okay it didn't really bounce but it just stopped so that's a bit of problem yeah it's not really good and let's see why is that let me see how it looks in with the balls being visualized okay first of all it's been stuck like this seems like the radius the checking radius looks bigger than what i have imagined looks like the multiple multiplication of two or this one just wanted to it's stopping looks all looks weird gotta fix this let's see why let me see so first thing to check is whether i am using uh if i'm using if i'm reusing any variable such as npt okay looks okay and this should always be more than two because of this condition so this should be always more than one so that should be okay i think an axis is and plus minus t plus this should also be okay i hoped yeah p scale near point should also be okay distance now okay first first thing that i want to try out is remove this conditioned and as soon as in added reflection vector value i'm going to break this so that these function only works once okay still have the same problem so it's not that okay the other possible things first of all i need to check if the condition is really correct so this one maximum radius is equal to one t plus new points all right then now i am wondering well anyway i think it should be okay and the distance pts and okay i am going to try to look for all the points starting from zero and well i think it's all right with one i think something must be wrong that's somewhere let me check [Music] okay let me see if i make this commented out so that's fine and let me also create some conditions to check whether if the point has met the conditioned or not by changing the color for easy check okay now what i want to do is to colorlize only if it collides so this is where i want to check and move this to here as well okay seems like the condition looks correct from what i'm looking at all right so probably the way i have calculated the reflectional value is wrong somehow and okay let me try to visualize this n axis or the reflection value itself okay as a marker ref value ref value to a vector value make it really high okay does it have it okay does and yeah it is creating some reflectional vector value somehow so coming from coming from coming to this way attached to this point creating this moving direction so seems correct this looks correct yeah so why it didn't really move that's the question hmm let me comment this out comment this out and update velocity directly at here and create a break let's see what happens okay now it bounced oops something went wrong here at least it is balancing so what seems to be wrong is with this average value velocity that i've created as soon as i create this average velocity add it this average velocity right here and apply the average velocity something went wrong funny why is that why is it okay okay okay i shouldn't have uh right shouldn't have updated velocity at this point because this condition we don't really know whether this condition mets for every point in this condition so uh okay so that that is why so i'm gonna create a count and create uh increment the count inside this this conditions right here then only if the count is more than zero then we can update the velocity with this average value and instead of using this one i can just use count all right i think that should work okay looks good now we do need to fix this conditions here it does collide but at some point maybe the speed wasn't enough for the collisions slowly merges so what if i make this when it touches the other balls make the speed a bit faster for the collision to go up to go to the other direction meaning how do i say the stiffness or the mass in physical term how do we call that um stiffness i guess is low when two point two balls contact each other create a bigger impact to move to the opposite direction okay looks good it looks too fast well we can control that by using some value here looks good i guess so let's go with this and if we check the so simulation with the ball nice i didn't intend to keep the collar about looks cool okay now on the final thing final thing that i want to do is to rotate this ball so so that it doesn't look like it's sliding okay to make it a bit more realistic so to do that let's go back to the sketch and think how we could deal with that looking from the top view or looking from the side view well in order to rotate the balls we need to rotate using the horizontal vector value as an axis perpendicular to the moving direction so if you're looking from the top view which is this one this is the horizontal view this is the moving direction i want to use this horizontal direction horizontal axis as a rotational axis to rotate the ball okay like that and amount of rotation can be retrieved by the amount of movement so getting the lengths of direction should give the magnitude of the direction will be directly converted into the angle the moving angle and in houdini in order to control the rotation you need to update the normal vector and up vector so by rotating these two vector values using this rotational matrix or something you'll be able to simulate this rotation for the ball right so shouldn't be that hard i'm gonna do everything inside this ball move point wrangle because it has the velocity informations inside and that's the information that i want to use to estimate the rotation information all right so let's do this first of all we need to create this horizontal vector value which is perpendicular to the current velocity which is this one and which is also perpendicular to a normal direction of this surface so by calculating the cross product between the normal direction and this velocity you should be able to get this horizontal axis okay so axis is equal to cross product between the velocity and the norm right and let's also make this normalized now we can use this to create a rotational matrix i'm going to name this root matte from identity matrix then rotate it by some angle which we don't know yet so let's just say angle and axis okay and what we want to do is to update the up vector by matrix and also a normal vector by matrix so that each of those two vectors will be rotated using this rotational matrix now what we want what we need is this angle here and this can be created from the moving distance of this velocity somehow right so i'm going to name this bellang and float velocity angle is can be retrieved by fit or just multiply the lengths of the velocity multiplied by pi multiplied by 0.5 i'm not sure what's the best value for the value yet so i'm gonna try with this value so pi multiplied by 0.5 means 90 degrees multiply by lengths of velocity and see if this is creating the correct rotation or not a spell mistake okay so let's see first thing first let's check if the normal direction of the ball is being rotated or not it's a bit hard to see because we have the surface but i i do see that somehow the normal direction of the ball is rotating let's just see it with the real geometry the ball geometry see if the ball is rotating in correct way or not now it is rotating but i think it's rotating to the opposite direction yeah i think the angle is opposite so let's make this negative now it looks more natural the direction of the rotation and the direction where it moves looks correct and the amount of angle also looks correct and i have now some okay there are some conditions some collision didn't really work like this one okay in those cases i guess i should create i should do other than i mean i think i should add additional reflectional vector value to this one so that if it touches together it also as additional like opposite direction goes from this point to this point for this point goes this way this point goes this way so in order to do that in order to do that let's see if we could do that right here actually it doesn't really give that option here i mean yeah you could but i'm not sure if this is the right place to do it because it also affects the boundary but i guess i also want to do it for the boundary conditions as well right right so let's say maybe not i'll just do it for this ball contact where we have calculate the reflection right here what i want to do is to instead of multiplying this by 1.5 i'm going to add additional velocity to this one which is negative and axis 5.5 or something which looks a bit too fast isn't it a bit hard point one i guess better than the previous one not really sure this might not be a good solution um but let's go with this for now the way it rotate looks good okay the ball stopped okay i guess i need to do the same things for the boundary so maybe instead of adding this value here i'm going back to the fractional functions and do it globally so in this case x-axis is the one that i want to modify it a little bit right [Music] so so how do i do this how do i do this i'm going to try to update the velocity by b plus x axis 5.5 and instead of using v we're gonna add it right here so it doesn't really create a correct like bouncing direction but at least we'll try to avoid now that's too fast isn't it i should reduce the length uh the speed to the original uh value so two to two how's this okay so we'll give you a better balancing effect i think and additional stuff that i could do is to change the noise speed maybe this one to be a little bit bigger so that it will change the the moving direction way faster so you have more roaming direction maybe that was too big making smooths a bit bigger yeah maybe that should do it a little a little bit bigger okay so so far i think i am satisfied with what i have got here looks looks like it is doing what i really want now about if i hide those uh wireframe you don't really see if the balls is rotating or not so let's try to colorlize this ball so that we do know that the ball is rotating um i'm just going to create a gradient color to this bowl from using y coordinate from zero to one and using the color node to color the sphere geometry based on the attribute using some kind of color matte like this one all right with these gradient color applied okay okay i should also delete the color attribute from this ball point all right now i can see the ball is rotating by looking at these textures okay looks good and let's also try to create some a little bit nicer material for these so that'll be easier to see the effect i'm just gonna use the matte cap shader for the surface and the bowls and use some of the textures that i have copied from internet which you could try to find it out from by yourself looking for the using some image search or anything i'm gonna try to use this one for the ball and this one for the surface okay so material this is for the bowl and this is for the surface so material is one and this is material two all right well looks like the color is a bit too vivid let's change this ball to something something like this nope now i cannot see the rotation so something else yeah this one all right looks good all right i like the effect now it's time to check if this could work on other types of geometry i've been checking with the plane but i also want to make this things work on three-dimensional geometry as well so try with sphere okay the initial output looks good if i play it seems like it's working yep that is because i have been using the surface normal direction as well as the tangent information as a guide so the surface could be any kind of shape so it is working for any kind of surface out of the box all right looks good let's try with the geometry with the hole we need to test out if everything works seems like it's working we do have a collisions between balls as well as collisions between the boundary okay let's do some stress test by adding tons of balls like 50 points oh wow and still everything seems to work fine yep no merging everything is working i think yep going back to the plane okay that was too much that was too much 30 points okay that's still a lot okay and as i can see everything is working as i expected you have a nice effect on any kind of surface with rotating wall balls right okay i think i am good with this all right so [Music] that's pretty much it um let me know if you have any um feedback a comment how you think about this i am going to gather all the parameters that i have set to one place so that i can control everything in one place and while doing it um i'll be appreciative if you have any like questions or anything i'm going to create a controller new node so first parameter i could create is a shape pattern shape variation which is this switch input currently i have three type let's say maximum is five okay anything else the number of points can be a parameter as well let's say from 1 to 100 initialize yeah we could set the initial speed or we could just say speed um how do i name this balls let's say max speed okay and minimum radius and maximum radius so ball min radius oh this was max and ball minimum radius right okay so that's for the initialization and we go inside a solver we i think we have a bunch of parameters inside here first of all looking at the ball move we have two noise related value so hey how do i close this noise smooth ball moving it still is related to ball so let's call this boil ball noise smooth and ball noise speed which is not clean not really clear what that is okay max speed is ball moving max speed well it it actually is i'm gonna delete it and this ball max speed that i've used for the initial speed can be given to this here as well so let's do that the acceleration speed is needed so ball acc speed okay so let's go back to the null node copy the ball max speed paste it to here all right anything else it's reasoning yeah this is also important this is for surface frightening ratio all right and for the this is or already been defined so nothing to do okay so that's pretty much it i think going back ups upward color for the wall this could be parameterized but i'm just gonna leave it as it is and yeah i think everything else is done so i'm just gonna connect it with the final that's pretty much it these are the parameters to control this you can change the number of balls okay i think i'm seeing some caches okay how do i remove these caches okay so where was i controlling the number of points speed if i make this speed faster goes really fast i do see some because it's moving too fast the trail is a bit more like uh how bugs move around so maybe i shouldn't make it too fast that might be too slow all right how about some comment from rudy what about permanently deforming the colliding sphere as collision occur uh well that's one another things probably you could do in those cases since i am just using points to calculate the collision between the points i'm not really having the ball information to the point so yeah i don't have those informations inside the points how it's been collided to calculate the deformation so if you want to do that you do need to keep the geometry informations while colliding inside the solver so that's another that's a bit different things to do if you really want to do that you should cop you should have the sphere from the initial information as an initial information input to the solver then calculate the deformation inside the solver because one point is not enough to store all the defamation information i think you do need to have all those point positions remembered um yeah i think it's gonna take some time to do it correctly so maybe another time i'll try that out okay well let me know if you have anything else okay i have a comment a line to one three one could you add a point for each collisions and move those points along with the sphere could you add the points for each collision and move those points along with the sphere let me see let me check what you mean by that so for baking deformation baking deformation wait a minute could you add a point so for each collisions there is a contacting point somewhere around here and oh i see and you want to keep that point positions as an information and use that later for deforming okay all right well that might work actually i can try that out yup let's see so [Music] for that purpose i gotta go inside this one gotta check where it has been contacted a bit which is inside here [Music] and when it has found the contact point this right here the contacting point is the middle point position between the end pause and t pause right so so this is the contacting point right now what i want to do is to create the new point at point and i think i gotta attach several information to this one so that you know that it belongs to the current point number so set point group first of all contact then also you need to you want to apply some parent information in which point it belongs to in this case i can i probably can just use pt number i think yeah i think maybe it's not a good idea to use the pt number but i should have an id value instead which won't change over time so going back to the initialize let's create an id derive from the pt number right then go back here set point group parent get the id all right and yeah okay and it's also in those cases we do we do need to rotate these points using the same rotational matrix actually so let's create the first thing first i need to find out every [Music] point which shares the same id so how do i do that um find attrib yeah this one okay i'm gonna use this one i'm gonna find all the attached contact point information by using well let's let's leave this for now and collect all the contacted vector value inside here well i think i should do this i should do this in other point wrangle because it's gonna be too complex to do it inside here so only thing i need to bring up to the next wrangle is this rotational matrix so let's have that apply to [Music] detail attributes shall we or not detail attribute to the point attribute so wait uh well let's deal let's do that set point a trip or just a wait a minute i forgot how i'm gonna access the matrix it was it m i think nope four nope [Music] what was the wait is this the error nope okay um [Music] yep four is correct m is wrong okay so four let's see do i have the rational rotational matrix yes yes okay yeah i do and now that i have it and project it to the ray node and i don't really need oh well okay um i think i shouldn't uh well because this ray node will change the point position of this point i also need to change the contact point position along with this ray node but it's a bit hard to do so instead of creating the new point position so instead of creating a new point i'm just going to create it as an attribute vector attribute value all right so to do that i first going to create an empty attribute for initialization somewhere around here let's name this v contacts like this which will create an empty vector value where is it yeah there is it there you go and this is going to be that variable that's going to be stored in each point which has this contact point position and which also should be rotated along with the point yeah and it the the value that's going to be stored inside a contact is not going to be the absolute value but rather it's going to be the relative point value so that even when the point moves around you don't really need to recalculate the point position but you just need to use this relative information to get the final uh point position right so shall we do that shall we do this okay yep i have removed the spam so where was i going back to the solver so the point position is this one the contact point position is this one and what i want is the relative position which can be calculated by contact minus the current center position which is p right or t pause which one is better not sure maybe this could be at p as well right so let's say this is the relative information related point position and what i want to do is to append this value to the contacts variable to the current point information so set point attrib zero to point at zero contacts current point number and you apply contact and append as an array all right so first of all we need to check if this is really working when the contact has been happened let's see so looking at the points looking at the mover points okay so yeah here you go i do have contacted points so when it becomes red it should give you those conducted points appended to this variable okay looks good now going back to the ball move what i do what i need to do next is to rotate this information with these and i don't actually need this anymore so what i do need is to access all the contacts array inside this points so four and of b contacts hmm all right now what i want to do is to rotate this contact using this rot matte and reapplied to a vector value again like this now let's see if it's if this is working [Music] so as you can see the value is changing over time which means it is being rotated hopefully alright and i also want to check if this position can be used to recreate the contact point all right so let's do this inside here to test out um test contact so for each point for each mover point well i have already filtered it here so for each point we want to access to the contacts and we want to add it as a point to see if it's in the right position or not not it and since this is a relative point position the actual point position is current point position plus contact and let's try to add a new point there and let's also colorlize this to see the difference make it green and let's see okay looks like we have something we want it does look like it is being a contacted points it's also being rotated together with the point so let's hope this is the right information to use going in back to the outsiders over and let's also copy this test contact code and try to use it somewhere somewhere probably somewhere around here and did it paste the test contact and for those newly added contact point i can change the group so [Music] setpoint group contact and let's also set the p scale to a i don't know how size of the current um b scale i don't know if that makes sense but just a test all right maybe that's too big i don't know and connect this to here and this copy to point only should only work for a mover all right let's look at and i'm going to make another copy two points node and to in order to make it easy to create a boolean shape i'm gonna make it as polygon instead of polygon mesh something like that and for second copy to point i'm gonna make this contact all right right now i don't have any contact points so nothing happens and do the maybe this boolean makes it too slow so maybe i don't really want to use this one but just to test this out all right don't need to solve self intersections or yes maybe okay and let's see what happens okay so as soon as it contacted it created the hole which looks too much which doesn't look natural but you can see the concept i mean at least it does what it has a starting point for the collision yeah since i'm using boolean the calculation is a bit too slow i don't really like the solution here but it does what it does i mean there should be more better way to deal with this maybe rather than using boolean i could use um bex to create some uh offset to the normal direction of the sphere so create the normal direction to the sphere and as soon as i created the sphere i could also get the contact point from here then based on this contact point i can deform the geometry if it belongs to the same points to do that i do need to know the id [Music] so after all i do needed the id value do i have that yes right so i want to attach the id attribute to this contact point as well just like this then create some deformations here so first thing first i want to get all the corresponding deforming point but to do that i'm gonna i want to make sure that this geometry has id transferred yeah it does so that's good and so um new points second input what was the parameter so geometry input number point position point group i should use this point group to filter out which point to look for so but when i use point group it's gonna be a bit slower although i think i need it so the filter is something like this or or instead i could do like that npts is find attrib val sharing the same id value one point id okay and search for all the and now i need to calculate the distance i think between the current point position and the new valid position if this is small enough then i'm going to create the deforming effect all right i'm gonna try it linearly first right based on the distance so if the distance is close create the high deformation uh if it's far then create a small deformation linear deformation right so i'm gonna have to set the maximum distance to search for should be relative to ap scale i think so max distance is the scale i don't know multiply by 0.5 gonna try with 0.5 for now and and let's create the fit value or age value how much i should deform so distance no fit distance from 0 to max distance if it's 0 the distortion has to be the maximum and it also has to be related to the p scale somehow so let's say 0.5 multiplied by p scale and 0 when it's far away all right then i can deform the point but um [Music] i should also keep use the maximum deformation result so [Music] i'm gonna create another rest positions for the sphere probably right here and calculate the current distortion or deformation value which is the distance between the rest and current point position and update the d form by getting the maximum between the deform and h right now finally update the point value by moving the rest to the negative normal direction multiply by uh actually this deform is always zero but anyway um the form uh well this is not a good solutions i realized because it doesn't keep the deformation when it starts to rotate with yeah well maybe it does maybe does let's see i see some cash result again okay let's see okay by having a contact okay nothing happened let's see why so there is a point here so something has something should have happened let's see why i'm gonna check what what i have i done i'm gonna check the deform value first of all see if some value has been created nope nope so something must be wrong um let's also check if we have a number of points here so i let's check the lens okay so there is several stuff here but the deform is equal to zero so something must be wrong inside the for loop okay the distance p scale wait a minute do i have this information [Music] i don't think i have that so that's the one that i'm missing i think i should copy p scale which has been yeah this one i gotta remove this value here all right now that i now i have something some deformations like this i gotta recreate the normal since i'm using a matte cap shader it doesn't really do anything but okay let's seize from the start yep you see that i am getting this deformation when ball touches together the resolution of the ball is a bit too low so the collision geometry the deformed result is not that smooth but you do see some effect ah well i could make this a bit higher resolution to make it a bit more smoother yep so it kind of worked i guess not sure if this is good enough for yours what you have asked but uh maybe this could be a starting point to do the update okay any more questions or feedback it'll be great if not i'm just gonna end this right here oh hey ln uh elaine thanks for the super chat i appreciate it so if there's no questions i'm gonna finish this and um i'm gonna update the files to the github so that you can download the files and check it out by yourself maybe this could be an additional parameter too that this one is small okay so that's pretty much it thank you very much for watching this so far it took like three hours to finish sorry for being late now hopefully you find this interesting as always i'm going to upload the files to the github just like i said and so that you can download it um [Music] from there i i'm going to paste the link to the video description page as well as uploading the files to the patreon page that i have so if you could support that will be also be great but you could always access the file for free okay that's it thank you very much i'm gonna upload it as soon as i finish this live and thanks for all the feedback comments and super chat i really appreciate it all right thank you and good night hopefully you have a nice uh night or day i'm going to sleep for now good night
Info
Channel: Junichiro Horikawa
Views: 179,417
Rating: undefined out of 5
Keywords: houdini, sidefx, live, tutorial, procedural, procedural modeling, parametric modeling, parametric design, parametric, fabrication, digital design, computational design, 3d, design, isosurface, lattice, structure, 3d modeling, modeling, computational, generative, line drawing, drawing, illustration, fractal, reaction diffusion, celullar automata, simulation, trail, particle, vfx, mitosis, magnetic field, field, volume, rendering, computer graphics, visualization, algorithm, motion graphics, graphics, remesh, quad
Id: Z_HCT5ZB-sc
Channel Id: undefined
Length: 199min 52sec (11992 seconds)
Published: Sun May 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.