Liquid-Surface-Simulation-Macros
by Tim Nikias Wenclawiak
Last update: 27.08.03
homepage: www.NoLights.de
First of all, the typical stuff
Please make sure that, when you're using these macros, my name and perhaps my homepage is mentioned somewhere in the credits, even if you're using modified versions of the macros. That is mostly more or less a moral issue. For people who actually make money in any way aided by these macros, I'd like to receive a note in which way, and would be happy to have a look at it. But since I don't expect anyone will actually make much money with these macros, but more with their own ideas, I don't want to have people think I'd want money for this. I don't. What is the System designed to do? Don't expect a full-blown liquids simulation system, with which you can pour wine out of a bottle or fill a glass of water. This system takes care of liquid surfaces (hence the name) and simulates waves. Due to the limitations of the underlying algorithm (which originally was an animated 2D-Effect for pixel-displacement on images), it doesn't handle splashes, shallow shores, foam or stuff like that. If you've taken a look at the example animations on my website, you should have a feeling what you can expect. Finally I hope the macros are useful and easy to use once you've grown accustomed with the concepts. If you've got suggestions for improvement of the code, ideas for additional macros or simply questions, feel free to mail me at tim.nikias@gmx.de. |
POV-Ray's Macros require you to hand some parameters. I've designed the macros for ease and efficiency in use at the cost of a little parsing time. Once the initial setup has been saved, all you need to specify for the other macros is a File-Identifier. The simulation makes heavy use of Hard-Drive I/O to move a handful of arrays from one macro to the next. This reduces the mistakes a User can make (because he can't mess something up to which he has no access). The LSS-File-Identifier is a string which should be unique for every Simulation in a scene. It provides the prefix for the the different files.
In order to use a macro, all of them require the LSS-File-Identifier as the first parameter, in order to let the macro know which simulation data to access. Additionally, other parameters are required, in most cases to set the wave-effects generated by the macro. If your OS supports filenames longer than the 8+3 digits (DOS-Standard), you may specify the Identifier as long as the maximum number of digits possible minus 4. The files will be named "[Identifier]_xxx.tmp", where xxx specifies the type of data saved within the file. All files are temporary and may be deleted AFTER the scene has been traced successfully (though it is recommended to keep the files until the entire animation is complete). Three macros are meant to be called once per simulation. LSS_Start and LSS_Stop are the obvious first and last Macros you'll use to begin and end the simulation process in any given frame. Right after LSS_Start, you may call LSS_Import, which imports a formerly exported Buffer (which may be done with LSS_Export). LSS_Environment is a macro which you'll have to call right after LSS_Import, or, if it isn't used, right after LSS_Start, since it will make heavy modifications to the simulation as a total. Note that the ex- and importing functionality is designed to be used for the same simulation, and takes care of loading a saved buffer instead of the default calm surface. Then there are "Adding Macros", which may be called several times and will add waves into the simulation. This applies to LSS_Rain, LSS_Drop, LSS_Path, LSS_Stomp and above all, LSS_Object. Additionally, there are LSS_UpdateTime and LSS_UpdateSpan, which update either time-settings or size-settings. The time-update is especially useful when you've finished a simulation and notice that you need an extra second or two. Without having to run the entire simulation again, you can just move onward using the older data, but with an enlonged timeframe. Finally, there are LSS_Visualize and LSS_PreVisualize, which return a mesh for the surface. LSS_PreVisualize may be used without the entire simulation, but requires the Global variables to function properly. It is only meant as a preview where the surface is placed, it doesn't show any waves at all. Throughout this Help, you'll find reference to the variable name "Animation_Time". This is a User-Set variable, and specifies the amount of seconds the current scene will render. All simulation-macros will then base their timing on this value, which runs from 0 to the specified second. Additionally, it might be helpful to declare "Animation_FPS". Normally, for movies you'd use a FPS (frames per second) of 25. If you want a 6 second animation, you'll thus use 6x25=150 frames. The FPS multiplied with the amount of simulation-seconds should be the minimum amount of steps you'd want your simulation to calculate, otherwise you'll get lots of frames which make use of interpolated steps, rather than new data. Using more steps will cause the waves to move faster. This variable sets the total amount of seconds which are being RENDERED. Subset-Framing and Resimulation The Simulation supports POV's subset-framing to a limited extent. The system doesn't save the state for every frame, but updates its data for every frame. If you jump back and forth between different sections of the simulation, it will resimulate the time up to the actual moment. By itself, the system will yield the same results as long as the same settings are used (and as long as the used macros are designed to do the same changes for the same steps, regardless of when they've been called. This is a special problem when using random-streams, and isn't easily overcome). Additionally, when stopping renders during parsing time, it may occur that you corrupt the data in the process. This happens when you interrupt while the system is writing data to disk. The system will handle this by "Resimulation". It will simply simulate all steps required to reach the actual moment, which may be pretty parsing-intensive, dependant on the amount of steps to be calculated and the amount of data used. In addition to keeping the simulation running properly, some corrupted files may be recalculated on the fly without harming the simulation at all. This applies to the final mesh, the default calm state of the surface and the DatSet, which tracks active and inactive nodes. For final runs, keep in mind that it is best to stop the render during the tracing-phase, and continue the image using the Continue_Trace-Option (commandline use is "+C"), in order not to lose the simulation-data. This is of especial importance for very detailed simulations, where tons of data is processed, which would be pretty time-consuming to resimulate. Last but not least, the two Updating-Macros LSS_UpdateTime and LSS_UpdateSize aren't functional for resimulation. They directly update the information of a simulation in order to reposition the surface or change the timing. Animations which make heavy use of these (this applies especially to LSS_UpdateSize, as it makes visually observable changes, e.g. rotation of the surface) won't calculate former steps properly. The subset-algorithm assumes the simulation is using the actual position of the surface and calculates everything based on that. If you modify the position during the animation, the algorithm will assume it has been in the new position from the beginning on, but this will only have effect as soon as the system tries to resimulate former steps. Keep that in mind when trying to do subset-animations with LSSM. |
Here's a complete overview of all macros that you may use in your scene files, along with the required parameters and an explanation. Initialization Macros LSS_Start - LSS_UpdateTime - LSS_UpdateSize - LSS_Export and LSS_Import Adding Macros LSS_Object - Place_LSS_Objects - LSS_Rain - LSS_Drop - LSS_Path - LSS_Stomp Final Macros This macro will generate the basic files. It is the very first macro you'll have to call to begin a simulation. It requires several predeclared variables, which are explained in detail later. Note that you MUST NOT exclude this Macro at any time in a simulation, as it updates internal timers and arrays. Once a simulation has finished, you might notice that you need an extra second or two. Just modify the timeframe of the simulation and alter the amount of frames rendered for the scene along with Animation_Time. If you then begin subset-framing at the frame you've reached before, the simulation will continue without resimulating. Note that it won't take a new beginning time into account until the simulation is restarted (either by rendering from the beginning again, or due to resimulation). During a simulation, you might want to move the surface. If you just translate it around, the other interactions won't line up with the surface anymore. That's why you should use this macro. It'll recalculate the corners and the topside of the simulation, but keeps all waves in their nodes. Useful to simulate rising water. Note that updating the size isn't handled as a movement, so when the moving surface interacts with an object, it won't cause waves unless the object itself is moving. Also, this macro isn't compatible with resimulations. LSS_Export and LSS_Import (Identifier, Filename) LSS_Export will export the current wave-data and the current mesh to the given file (which is a complete filename, e.g. "filename.end"). Note that it will use the data currently active at the moment LSS_Export is called, so this is best used after LSS_Stop. LSS_Environment (Identifier, Environment-Object) This macro will recode the data to properly simulate waves reflecting off of walls and other objects. This macro is designed to be called right after LSS_Start, and is meant to be called only once. The specified Object needs to be unanimated and unmoving. To use moving Objects with the simulation, use LSS_Object. Also note that depending on object-type (CSG, mesh, etc) you need to specify the Inside-Test to use Mesh-Support. LSS_Object (Identifier, Array of Strings, Array of UV-Timeframes, UV-MinSpeed, UV-MaxSpeed, Detach-Height) For Objects to interact with the surface, they need to fulfill certain requirements, which are explained later. They are then handed to this macro by filling an array with strings, each being the name of the object-macro. Detach-Height is a float which defines the height of waves caused when the object fully "exits" or "enters" the surface. When a node isn't blocked anymore, a wave will be placed. This will counter the LSS_Obj_Memory effect in order to introduce these waves. If Detach-Height is 0, this feature is switched off. NOTE: During my testing-phase of the simulation-process, I've found that waves caused by objects easily add up to four or five times the specified height. If sudden peaks appear near an object, this may be due to that, and you should try reducing the height of the waves or broaden the speed-limits you've put on the macro. NOTE #2: This macro will output a Text-File named [LSS_Identifier]+"_ofs.txt". The value saved in this file is the highest speed introduced by objects during the current simulation. It is reset to 0 once a simulation is restarted. Place_LSS_Objects (Animation_Time*clock) This Macro was added to easily place all objects that have been supplied to the latest LSS_Object. It will position and animate them according to the latest macros. If you redefine a macro that has been used for LSS_Object after its use, and then call this macro, the results won't be the same as used for the simulation. Thus, it is best to use this macro right after LSS_Object. Note that before and after an object has reached its timeframe, it will stay motionless where it begins/ends. LSS_Rain (Identifier, Drops per Step, UV-Heightrange, Timeframe) This macro will drop the specified amount of waves per step into the simulation. Their height will be a random value between the u and the v component of the UV-Heightrange. The waves will be dropped during the given Timeframe. LSS_Drop (Identifier, Position, Magnitude, Time of Impact) This macro will place a single wave at the given position, at the given time. If the position is above or below the surface, it will be mapped onto it. The height of the initial wave is set with magnitude. Obviously, Position is a vector, whereas Magnitude and Time of Impact are floats. The time of impact is, as always, a float ranging from 0 to Animation_Time. The wave will be dropped at the specified time, rounding up or down towards the nearest step where necessary. LSS_Path (Identifier, Path-Name, Emitter-Vector, Step-Check, Timeframe) This macro requires another macro which defines a path in 3D-Space. The name of that macro is handed to the LSS_Path-Macro as a string. The given Macro needs to be based solely on one float-parameter, e.g. #macro This_Path(X) [...] #end and returns a 3D-Vector, or to be more precise, a position. The Emitter-Vector is used as follows: Note that unlike LSS_Object, this macro only introduces waves in relation to its position, not its speed, and is best suited for effects which would only create uniform-height waves, e.g. an insect swimming on the surface. LSS_Stomp (Identifier, Magnitude, Time of impact) Given a magnitude and a time of impact (as always in relation to Animation_Time), this macro will cause the environmental object to create waves where the liquid surface touches the environmental object. This is similiar to the effect seen when banging a table with a glass of water on it. The shockwave will travel through table and glass and emit into the water, causing a wave. This is the last macro you will call for the simulation. It gathers all modifications made to the data by the various Macros, and calculates the next step(s) of the simulation. After that, all you need to do is use LSS_Visualize to generate a smooth-mesh for the surface. This macro is actually an inbuilt composition from my Mesh-Modifying-Macros. It loads the final data of the simulation, generates the normal-vectors required for the smooth_triangles, and builds the mesh. You should embrace this macro with object{} in order to texture the mesh. This macro is suited to just read the Corner-Positions and generate a minimal mesh from that (two triangles). It is used to position the surface before doing any kind of heavy-duty parsing. Set the system and comment the simulation macros out (not this one though). Now check if the position of the surface is correct using PreVisualize instead of LSS_Visualize. When everything is as desired, just delete the "Pre" and uncomment the simulation-macros. This is an internal macro which may be of use for other purposes as well. It reads the final data of the simulation and returns a twodimensional array, in which every index specifies one node of the rectangular grid. Internally, it is used for LSS_Visualize to model the surface, but if you've got other methods of visualizing the different nodes, this provides the required data. It simply returns an array and should be used as follows: #declare/local Mesh_Position = LSS_Get_MeshDat("Some_Sim"); |
LSS_Start initializes the data and prepares it for the next steps in successive frames. Aside of initializing and updating timers and arrays, it also checks for corrupted data and resets the simulation in case it is needed.
To function properly, it relies on several global declarations the User has to set before calling the macro. The System, once loaded into the scene, provides some default settings, so leaving one out won't crash the parsing process. Here's a list of their names and functions. External Functions LSS_Debug - Animation_FPS - Animation_Time Main variables LSS_FileHandle - LSS_Beg and LSS_End Detail variables LSS_StepAmount - LSS_NPU - LSS_Dampening - LSS_TightEnds Internal Functions LSS_ClipHeight - LSS_Mesh_Support - LSS_Obj_Memory - LSS_Seed - LSS_CleanUp External variables This variable switches debugging messages on and off. Note that you may reset this anytime. Once set to on, Macros will issue messages, once set to off, they won't. Very simple and sometimes useful, but unless you're scripting some own macros, only useful to make predictions how long the parsing might take (based on how fast your CPU calculated less nodes, or more steps, or whatever in former runs) and to see how far the simulation has already progressed. Every animation has a FPS, a number describing the amount of Frames Per Second. A normal movie, for example, has 25. The number indicates how many frames you'll later use to encode one second of the animation. Animation_Time (Default=Total_Frames/Animation_FPS) This float describes the amount of seconds you'll be animating in this scene. All timeframes you'll set for the LSS-Macros are relative to this timing. A more detailed description for this can be found above. Main variables LSS_FileHandle (Default="water") This variable set the prefix for the files created by and for the simulation. On old DOS machines, the filenames were built of 8 characters + 3 characters for file-ending. Win95 and higher (Linux would count as higher... :) support long filenames. Since the system adds a "_xxx" to the given string and uses ".tmp" as ending to build the filenames, on DOS machines this variable has to be limited to 4 characters. On other OS its (of course) the maximum amount of characters per file minus 4. Keep in mind that his variable is the name the simulation will run by and identifies itself for the other macros. LSS_Beg (Default=0) and LSS_End (Default=Animation_Time) These two set the Beginning and Ending time of the simulation. The surface will remain motionless until the timeframe has been reached, and will "freeze" once the timeframe has passed. Also, no heavy-duty calculations are done until timeframe is reached (aside of one initial step, which is always required). LSS_Corner_1 - 3 and LSS_Above (Defaults = <0,0,0>; <0,0,1>; <1,0,1>; <0,1,0>+LSS_Corner_1) The three corner variables span the rectangle. Think of it as successive steps. Since three corners only creates a triangle, the fourth one is generated by these three. To properly set the corners, imagine drawing the initial triangle from corner to corner, where you want to avoid the diagonal which will be inside the final rectangle. The "Above" variable is required to determine the topside of the surface, and model wave-hills as hills, and not as valleys. Detail variables LSS_StepAmount (Default=Animation_FPS*(LSS_End-LSS_Beg)) This sets the amount of steps in the simulation of the surface. Recommended is an amount equal to the number of frames, you may specify more. Using less will result in interpolated steps, which may look strange in certain situations, but is useful for previews. Note that the speed of waves is dependant on NPU and Step-Amount, since a wave will travel from one node to the next (sort of) per step. NPU refers to Nodes Per Unit. The simulation relies on discrete intervals on the surface. These are referred to as "nodes of the surface". On a one by one Rectangle, a NPU of 5 would place 5x5=25 Nodes for simulation into that rectangle. As mentioned under LSS_StepAmount, the speed of waves depends on NPU and Step-Amount, since the simulation moves waves from node to node per step. After each step, the waves should be dampened a tiny bit to ensure that waves will eventually settle. The waves' height will be multiplied with this value in each step, and should always be smaller than 1 and larger than 0. You may change this value during the simulation process to alter the dissipation of waves to a certain degree, but note that resimulations will just use the actual value. Dampening is the only variable which isn't hardcoded into the simulation, but should be used with caution. Values larger than 1 or smaller than 0 will yield VERY unrealistic results (values smaller than 0 will result in waves swapping from valley to hill once per step, values larger than 1 just increase a waves' size, it won't dissipate, but grow). Sometimes, strange wave patterns may appear, the most common and visually worst is a checker-like pattern. These artifacts, because of the nature of the underlying algorithm, would normally just dissipate like any other wave, and don't make too much trouble in open areas, where these artifacts may easily dissipate. It does pose a problem when it occurs in tight corners, where several nodes don't have all their neighbours. Due to less neighbours, the effect dissipates very slowly, and thus becomes obvious, especially when the rest of the surface has already calmed down. To avoid this, I've implemented a variable dampening, which works in relation to the amount of neighbours a node has. The value given with LSS_TightEnds is a multiplier for LSS_Dampening, which is used when no neighbour is present. The value interpolates to a value of 1 when all neighbours are active. In effect, corners are dampened more, and open areas are always left untouched. The value I've chosen as default is normally sufficient and needn't be worried about unless you run into some major wave-artifacts yourself. Internal Functions This variable does what its name implies: it clips the height of waves. Setting it to 0 leaves it off (no use in clipping waves to zero height, is there?). Only the absolute value is used (negative numbers are treated as positive). This variable is not a boolean on/off, but a 0, 1 and 2 switch. 0 sets the tests to only use POV's inbuilt inside-function, which is only suited for POV's native CSG, but doesn't support objects with undefined insides (like a mesh, which is the most famous example for that). Method 1 will just shoot rays upwards through the object it is hitting and count the amount of surfaces it encounters. If its uneven, it assumes being inside a mesh, and returns the inside-test as true. When using Object-Interaction with the simulation, it may happen that objects are trailed by a very turbulated area. This occurs when waves are reflected off of the object in one step, but may move on freely in the next. This depends heavily on NPU and the wave-settings of LSS_Object. To work around this, I've set sort of a memory for the nodes. If they have been blocked, they'll remain blocked for a given amount of steps after they're set free. The value should be low and is meant to take care of waves caused by the object itself, which would interact with free nodes in the next step. Keeping nodes calm for two steps has proven sufficient for most cases, and isn't visually obvious. This variable sets value for a random stream, which is so far only used by LSS_Rain. Unless you want the rain to be the same for every surface, you might want to issue a different number for each simulation. Every now and then the data should be checked for wrong entries of wave-emitters. By default, it is off, any other integer defines the amount of steps made until data is checked. Using the supplied macros the data doesn't require cleaning, but when creating your own macros which are to interact with the data, this takes care of some mistakes you might make (which isn't intended as a pun: you haven't written the script and might interpret things I'm actually doing wrong). |
Objects interacting with the simulation need to fulfill certain requirements. Some of these apply to objects meant for the LSS_Environment Macro as well as to the objects meant for the LSS_Object Macro, some are meant for one only.
POV-Ray has a native, inbuilt float-function called inside(). It uses two parameters, an object and a position. It will return true if the position is inside the object. This only works for objects which have a well defined inside, like spheres, boxes and cones; They may be used in CSG-Operations and are "solid" objects. This doesn't apply to (for example) meshes, which are just a bunch of triangles which may or may not enclose a volume. Look in the POV-Docs for more information on this. For both Macros, LSS_Environment and LSS_Object, to work properly, I need a method with which I can find out if a node of the simulation is inside an object, or outside. To do this, I use the inside()-function. But what when a User wants to use meshes? To solve this, you may declare a variable named LSS_Mesh_Support PRIOR to calling the LSS_Environment or LSS_Object Macros. It sets which type of inside()-test to use. Method 0 is the simple CSG-Type, Method 1 shoots rays upwards through the object and counts the amount of surfaces hit. If it is uneven, the test assumes its inside an object. Method 2 shoots rays up- and downwards. If the object is hit in both directions, the test assumes its inside an object. For known issues with internal surfaces, objects handed to the system should be wrapped not with a union{}, but with a merge{}, when using Method 1. This gets rid of internal surfaces as long as some CSG objects are being used. Since you'll be handing identifiers, not actual objects to the macro, you can of course specify one object for the simulation's calculations, and use a different object in the scene. The object handed to the LSS_Environment macro needs to fulfill above mentioned specifications, additionally, it has to be static. LSS_Environment "hardcodes" a node's state to disk and excludes dead nodes from the calculation process to save parsing time. Effectively, LSS_Environment is meant to specify a "solid" structure in which the simulation takes place. Moving and altering objects are meant to be set with LSS_Object. If you alter the simulation's surface during an animation using LSS_UpdateSize, you'll have to use LSS_Environment again. Objects handed to LSS_Object need to be declared inside a macro, which takes only one Parameter: float X. It should fulfill the merge-requirement from above in case you want to use Mesh-Support for objects. As an example, here's a setting for an object: #macro Some_Object(X) It is essential that the macro only takes one parameter, which is a float. You can use any other name, it doesn't have to be X. Just remember that its a float which will range from 0 to 1 when called. This 0 to 1 value represents the timeframe of the object which you specify in LSS_Object, but I'll return to this later. Every object then requires an additional Transformation-Macro, which MUST have the same name as the object-macro, but requires an additional "_Transform" at the end. For already given example, this would be: #macro Some_Object_Transformation(X) Again, X may be any name, and is a float. For the LSS_Object to identify the objects it is using and to animate them, you hand the object's name as a string inside an array. For example, above object would be set as following: array[1] {"Some_Object"} There is no need to specify the transform-macro, the system will do that by itself. As a second parameter, LSS_Object requires another array, this one being filled with UV-Vectors. The first and second array given to the macro should have the same size. Every index of one macro (the name of the object-macro) is paired with the same index of the timeframe-array. The UV-Vector specifies the beginning and ending time for the object's movement. These values are given in seconds and relate to (you should have read that often enough by now) Animation_Time. The simulation-macro will then take care of the rest. It will convert the UV-Timeframe into the above mentioned values ranging from 0 to 1, and these are also set according to the timeframe of the simulation itself. But you don't need to clutter yourself with these thoughts: just set a timeframe for the objects, and the macro will take care of the rest. LSS_Object calculates the speed of an object by reverse-transforming a given position to its initial state, then transforming it back to a state just before the actual moment. The distance between the two positions is used to determine the speed, because the object's part which is now blocking a certain node has travelled the calculated distance in a given time. Obviously, this approach may run into trouble when pure rotation is being applied to the object. There is also no guaranteed method to derive the rotating speed if the rotation is too fast for the time-intervals used by the macros. But simulations running on discrete steps always have the problem of data being missed in between the steps, so please don't complain about that. Just raise the steps. |
The simulation makes use of some internal variables which may be of use. Above all, Total_Frames and Cyclic_Animation are two variables which can be used to determine the amount of frames in the animation and if its a cyclic animation. Total_Frames was scripted because I needed an automated way to find out how long the animation might be with a given FPS. Since POV's final_frame only returned the frame number of the last frame rendered (and with subset-framing, that isn't always the very last frame of the animation), I calculated the amount of frames based on frame-numbers, clock-values and clock_delta. As a requirement of these calculations, I needed to know if the animation is cyclic or not, because with a cyclic animation I wouldn't reach the value 1 for the clock, and would thus return one frame too much. You may of course copy and paste the algorithm for these two variables out of the include-file, in case you need it at other places as well. Just always remember the nice little crediting I mentioned at the beginning. |
In order to give the User more flexibility on how to use and what to do with the System, I've implemented a preprocessing macro named LSS_PPS_Buffer, which will be called before every step, and may be used to make changes to the wave-buffer during the runtime. It is not so much meant to create actual new effects, but rather enhance and modify the existing wave-pattern in any degree on a step-by-step basis.
For example, if you'd want a certain region of the simulation to stay totally calm at all times, you may use the macro and set certain nodes to 0. To properly work with the macro, some background information is required: The buffer is a 3D-Array. The first dimension accesses one of the three internally saved states of former steps. The array is handled as a ring-like structure, which means that the oldest step will be overwritten by the newest. Thus, in order to access the correct steps for modifications, a Swap-Vector is used. It saves the actual step in x, the former step in y and the one even before in z. To modify the buffer properly, you don't need to modify the actual step, as it will be generated AFTER the preprocessing macro has been called. The two steps before are used as basis for the new step. I don't want to explain the code in detail here as much better descriptions can be found all over the net, but it is sufficient to say that the former step is used as basis and gets the second-last step subtracted in order to build the new step. Do note that some more calculations are done to determine wave reflections, dissipation etc, but these are none of your concern with the preprocess macro. Another two useful variables that may be used inside the macro are Y_Size and Z_Size, which are set to the size of the 2nd and 3rd dimension of the Buffer-Array. This provides easy setup of the loops to parse through the entire array. One example for a preprocess may be downloaded on my website and shows how to create a small river-like stream. What it does is to move the data "downstream" by two or more nodes. Inside of objects, the waves are terminated (all buffer entries set to 0) using a macro specifically written for the preprocess macro: LSS_PPS_GenerateActive(). All it does is to return a two-dimensional array filled with 0s and 1s: 0 for "inactive/blocked node" and 1 for "active node". While parsing the buffer inside the preprocess macro, each node marked with 0 will just get nullified. Here's an example for a "clean-up" macro, which will terminate waves that have somehow gotten into inactive nodes: #macro LSS_PPS_Buffer( _Buffer , _Swap) |
LSS_Start | 1. LSS_Identifier
Requires several global variables to initialize properly |
|||
|
||||
LSS_UpdateTime | 1. LSS_Identifier
Resets timing of running simulation, set with global variables |
|||
|
||||
LSS_UpdateSize | 1. LSS_Identifier
Resets size and position of surface, set with global variables, requires rerun of LSS_Environment |
|||
|
||||
LSS_Export | 1. LSS_Identifier
2. Filename to which the current Buffer shall be exported |
|||
|
||||
LSS_Import | 1. LSS_Identifier
2. Filename of previously exported Buffer |
|||
|
||||
LSS_Environment | 1. LSS_Identifier
2. Object-Declaration used as a static-environment |
|||
|
||||
LSS_Object | 1. LSS_Identifier
2. Array of Strings (Names of Object-Macros) 3. Array of Timeframes 4. UV-Vector for <Minimum Speed, Height of Wave> 5. UV-Vector for <Maximum Speed, Height of Wave> 6. Unblocking nodes cause a wave of this height |
|||
|
||||
Place_LSS_Objects | 1. Animation_Time * clock | |||
|
||||
LSS_Drop | 1. LSS_Identifier
2. Position of Drop (will be mapped onto the surface) 3. Height of Wave 4. Moment of impact |
|||
|
||||
LSS_Rain | 1. LSS_Identifier
2. Amount of rain drops per step 3. UV-Vector for <Min-, Max-> -Height of waves 4. Timeframe |
|||
|
||||
LSS_Stomp | 1. LSS_Identifier
2. Height of Wave 3. Moment of "Impact" |
|||
|
||||
LSS_Path | 1. LSS_Identifier
2. Name of Macro (as string) which returns a position 3. Vector with x=Radius of interaction; y=Height of wave when Touching; z=Height of wave when barely touching 4. UV-Vector with u=Amount of Steps to check for non-movement; v=height of wave if check successful |
|||
|
||||
LSS_Stop | 1. LSS_Identifier | |||
|
||||
LSS_Visualize | 1. LSS_Identifier | |||
|
||||
LSS_PreVisualize | 1. LSS_Identifier | |||
|
||||
LSS_Get_MeshDat | 1. LSS_Identifier | |||
|
||||
1. Buffer Identifier, should be replaced via #declare inside the macro
2. Swap-Vector, used to access the different steps |
||||
|
||||
LSS_PPS_GenerateActive | None, just returns 2D-Array of active (1) and inactive (0) nodes |
|