MegaPOV 1.0
Copyright © 2002 MegaPOV-Team
31 December 2002
Abstract
This documentation contains a complete set of information about MegaPOV. Here you can find descriptions from either script and patch writer point of view. This work is supposed to be an addition to complete the POV-Ray™ Documentation.
Table of Contents
List of Figures
List of Tables
List of Examples
Table of Contents
MegaPOV is a custom and unofficial patched version of POV-Ray™. It is a compilation of separately released patches and techniques released within the POV-Ray™ Community and dedicated work of the MegaPOV-Team.
Many patches from MegaPOV 0.7 were included in official POV-Ray™ 3.5. It will probably not happen with patches included in MegaPOV 1.0 and later because POV-Ray™ in the future will be rewritten using C++.
MegaPOV 1.0 is a fresh start, based on the sources of POV-Ray™ 3.5. This means that not all features of MegaPOV 0.7 are implemented yet. Another consequence is that for several features the new syntax of POV-Ray™ 3.5 is now used. Here is a list of added features:
Features in MegaPOV 0.7 that didn't make it in POV-Ray™ 3.5, but which are back in MegaPOV 1.0;
PoPOV has joined MegaPOV.
Some people may wonder why a MegaPOV version is still maintained when most MegaPOV features have been incorporated and improved in POV-Ray™ 3.5. Here are some reasons why:
So the MegaPOV-Team collects available patches, tries to merge them into one patch collection and makes it available for the most common platforms.
MegaPOV features are enabled by using:
version unofficial megapov 1.0; // version number may be different
The new features are disabled by default, and only the official version's syntax will be accepted. The above line of POV code must be included in every include file with MegaPOV features as well, not just the main POV file. Once the unofficial features have been enabled, they can be again disabled by using:
#version 3.5;
This is useful to allow backwards compatibility for some features.
Packages with compiled binaries are available for the most common platforms. They can be obtained at the MegaPOV site where you can also find the source code.
The Mac version with its special user interface is maintained separately on Smellenbergh's site.
An online version of the MegaPOV documentation as well as downloadable archives in various formats are located at the MegaPOV site - documentation section.
A preview of the samples coming with MegaPOV can be found on Smellenbergh's site - demo section. The thumbnails there have a link to a larger image (640*480) and some description as well as the zipped sources are available there.
![]() | Note |
---|---|
None of the MegaPOV packages includes the official POV-Ray™ documentation, samples and include files although these are essential for using MegaPOV. If you do not already have installed POV-Ray™ you should get the official version from the POV-Ray™ website. |
We don't maintain our own forum for discussions. MegaPOV is an unofficial patch to POV-Ray™ and the MegaPOV-Team is just part of the POV-Ray™ Community. That's why you can use the povray.unofficial.patches group for discussions related to MegaPOV. You can also use povray.binaries.* and povray.text.* groups to upload files related to MegaPOV. All mentioned groups are located on news.povray.org.
Table of Contents
The Frame_Step=n (+STPn) option introduces breaks in the order of rendered steps. It splits the order of rendered frames into a 'virtual' and a 'real' order.
'Virtual' order is the same as the traditional (used in POV-Ray™ 3.5) order described with Initial_Frame, Final_Frame, Initial_Clock, Final_Clock, Subset_Start_Frame, Subset_End_Frame. This order is what the scripts reads from initial_frame, clock_delta and other animation related build-in tokens in SDL.
'Real' order is a subset of 'virtual' order. It is every n-th frame where n is the value of Frame_Step. Selected frames are reordered (with ascending or descending order) according to the sign of Frame_Step option.
Frame_Step is supposed to use parallel rendering over one source with one location shared between instances of renderer.
Example 2.1. Influence of Frame_Step on generated files
The following command line:
megapov +Iscene.pov Initial_Frame=1 Final_Frame=5 +FN
causes the creation of files in such order:
scene1.png scene2.png scene3.png scene4.png scene5.png
while when using Frame_Step:
megapov +Iscene.pov Initial_Frame=1 Final_Frame=5 +FN Frame_Step=-2
causes a subset of it in the following order:
scene5.png scene3.png scene1.png
![]() | Important |
---|---|
Frame_Step different than 1 works fine for those animations where variables are not passed between frames when using external files and where the next frame does not use values derived from a previous (in the meaning of virtual order) frame by other ways. |
POV-Ray™ 3.5 does not allow the End_Row command line option (+ER) to be 1, but rather forces the value, indirectly, to be the last row in the image. Basically it seems to be impossible to render the top row of an image by itself. MegaPOV contains a fix for this behavior. The change also makes the +SR/+ER flags consistent with the behavior of the +SC/+EC flags.
The #set keyword modifies the most recently created version of a variable. So, if a variable has been created previously with either #declare or #local, its value can be changed with the #set directive.
Example 2.2. Using the #set directive
#declare MyCounter = 0: #set MyCounter = MyCounter + 1;
One advantage is that it makes it more visually clear where variables are 'created', and where they are only 'changed'.
Another advantage is that if you try to change a variable that doesn't yet exist, it produces an error. This could happen if you make a typing mistake, like this:
#declare MyCounter = 0; #while (MyCounter < 10) #declare MyCountr = MyCounter+1; #end
This would normally cause an infinite loop, and may take a while to track down, especially in complex scenes and with typos that "look right" at a glance. If #set was used, it would cause an error ("#set cannot assign to uninitialized identifier MyCountr.") at that line, pointing you directly at the problem.
POV-Ray™ 3.5 in its official release does not accept all built-in constants and variables to be used in functions. Following tokens are recognized additionally in VM since MegaPOV 1.0: clock_delta, clock_on, false, final_clock, final_frame, frame_number, initial_clock, initial_frame, image_height, image_width, no, off, on, true, version, yes . All mentioned tokens return the same values as in the whole SDL parser.
As other animation options, also Frame_Step has its own equivalent in SDL. You can use the frame_step key-word to get the value which was passed to Frame_Step (see Section 2.1.1). Default value is 1.
With the keyword date, time and/or a date can be used in your images. This might be useful in a macro to place a time stamp in your images, along with your name. The keyword date works like other string functions, except that you have to supply a format string.
Example 2.3. date function usage
Suppose it's Saturday 1 January. The following script:
#declare TheString=date("%a %B")
will return the string: Sat January
The most flexible implementation was chosen (which is probably not the easiest ...) because not all countries write dates in the same way. Just think of the difference between the USA and most parts of Europe. These are the possible specifiers for the format string: Please note that these should be equal for all platforms but if you don't get the expected result, contact the person who compiled your version to find out if there are differences.
Table 2.1. The following time formatting strings are available:
a | Abbreviated weekday name. |
A | Full weekday name. |
b | Abbreviated month name. |
B | Full month name. |
c | The strftime() format equaling the format string of "%x %X". |
d | Day of the month as a decimal number. |
H | The hour (24-hour clock) as a decimal number from 00 to 23. |
I | The hour (12-hour clock) as a decimal number from 01 to 12 |
j | The day of the year as a decimal number from 001 to 366 |
m | The month as a decimal number from 01 to 12. |
M | The minute as a decimal number from 00 to 59. |
p | "AM" or "PM". |
S | The seconds as a decimal number from 00 to 59. |
U | The week number of the year as a decimal number from 00 to 52. Sunday is considered the first day of the week. |
w | The weekday as a decimal number from 0 to 6. Sunday is (0) zero. |
W | The week of the year as a decimal number from 00 to 51. Monday is the first day of the week. |
x | The date representation of the current locale. |
X | The time representation of the current locale. |
y | The last two digits of the year as a decimal number. |
Y | The century as a decimal number. |
z | The time zone name or nothing if it is unknown. |
% | The percent sign is displayed. |
![]() | Note: |
---|---|
To use the '%' character in the result, use it twice: date("%%") |
Refer to date.pov for an example scene. Please note that you might have to write the result in a file if you want to abort the rendering and continue later on. Otherwise you could get a different result because time goes on :-)
The keyword start_chrono sets an internal variable and returns the current internal clock counter of your computer. The return value is not important. However, you must assign this return value from start_chrono otherwise you get an error. Use it like this:
#declare Stopwatch = start_chrono;
or use it like this:
#if (start_chrono)
but not:
start_chrono //parsing stops with a fatal error
The keyword current_chrono returns the time in full seconds (no fractions of seconds) between start_chrono and current_chrono. The start value is not changed. A second current_chrono will still return the seconds between start_chrono and the second current_chrono.
If you don't call start_chrono somewhere before you call current_chrono, you will get the seconds elapsed since the beginning of the current render (parsing).
Example 2.4. Using the timer function
//reset the chrono and return the internal clock counter #declare ParseStart = start_chrono; ... syntax to be parsed //read the seconds elapsed since chrono_start #declare ParseEnd = current_chrono; #debug concat("\nParsing took ",str((ParseEnd, 1, 0)," seconds\n")
Refer to chrono.pov for a demo scene.
MegaPOV delivers new pre-defined functions. These new internal functions can be accessed through the mp_functions.inc include file, so it should be included in your scene.
f_triangle function has 10 parameters:
FLOAT f_triangle(
FLOAT V1x, FLOAT V1y, FLOAT V1z, FLOAT V2x, FLOAT V2y, FLOAT V2z, FLOAT V3x, FLOAT V3y, FLOAT V3z, FLOAT Thickness)
;
The parameters V1x, V1y, V1z describe the coordinates of the first vertex in the triangle.
The parameters V2x, V2y, V2z describe the coordinates of the second vertex in the triangle.
The parameters V3x, V3y, V3z describe the coordinates of the third vertex in the triangle.
The parameter Thickness describes how thick the triangle is.
![]() | Note |
---|---|
In order to achieve the fastest calculation, try to pass the parameters so that the side V1-V2 represents the longest side and V1-V3 represents the shortest side. |
The polynomial solver is accessible from scripts via the float functions n_roots and nth_root with the following syntax:
INT n_roots(
FLOAT an, ..., FLOAT a0, BOOL sturm_flag, FLOAT epsilon)
;
FLOAT nth_root(
FLOAT nth, FLOAT an, ..., FLOAT a0, BOOL sturm_flag, FLOAT epsilon)
;
n_roots returns the number of roots derived from the polynomial given by the parameters an, ..., a0 and calculated under the conditions specified by the parameters sturm_flag and epsilon.
nth_root returns the value of the nth root of a given polynomial.
The sturm flag turns on a different algorithm of calculation. Its usage influences the number of returned roots. Epsilon (positive) value means that the roots below Epsilon value are ignored. Epsilon=0 means that none of the roots are ignored.
![]() | Important |
---|---|
You don't have to call n_roots before nth_root, but if you do call nth_root with the wrong root number then it causes an error and breaks parsing. It is better to call n_roots first to verify the number of available roots. |
Example 2.5. Polynomial solver usage
Imagine that we have x3+6*x2-x-6 and that we are interested in its roots for further calculations. So if we declare:
#declare N=n_roots(1, 6, -1, -6, off, 0);
then N has value 3 because the mentioned equation has 3 roots. If we are interested in what roots it has, we can use the following calls:
#declare R0=nth_root(0, 1, 6, -1, -6, off, 0); #declare R1=nth_root(1, 1, 6, -1, -6, off, 0); #declare R2=nth_root(2, 1, 6, -1, -6, off, 0);
And it returns R0=-6, R1=1 and R2=-1. So finally we know that x3+6*x2-x-6=(x+6)*(x-1)*(x+1) .
Splines in POV-Ray™ can be used to create objects by its rotation, translation or being a border of surface. Usually it is hard to follow those surfaces with calculations developed in SDL because they are mostly hard coded within the source core code of POV-Ray™. The spline feature introduced in POV-Ray™ 3.5 makes such operations much easier but some spline types are still missing. sor_spline is introduced to access the surface of the sor object in SDL.
To use the data from the sor object in sor_spline, the order of coordinates has to be changed. The old y coordinate is now the clock value in the spline. The advantage is that one sor_spline can hold data from five old sor-s. That's because every spline can operate up to five dimensions along the clock value.
Example 2.6. Conversion from sor object definition to sor_spline type in spline
spline{ sor_spline -1.000000,0.000000*x 0.000000,0.118143*x 0.540084,0.620253*x 0.827004,0.210970*x 0.962025,0.194093*x 1.000000,0.286920*x 1.033755,0.468354*x } sor{ 7 <0.000000, -1.000000> <0.118143, 0.000000> <0.620253, 0.540084> <0.210970, 0.827004> <0.194093, 0.962025> <0.286920, 1.000000> <0.468354, 1.033755> }
Since MegaPOV 1.0 it is possible to read values stored in spline with a notation similar to the array. Previously once spline was declared, it was only possible to evaluate it for a specified argument. Now two new usages are possible: you can get the number of entries and read the exact values placed in splines.
SPLINE_USAGE: SPLINE_EVALUATION | SPLINE_MEASUREMENT | SPLINE_ENTRY SPLINE_EVALUATION: #declare Spline_Value = MySpline(Val); #declare Spline_Value = MySpline(Val, SPLINE_TYPE); SPLINE_MEASUREMENT: #declare Number_Of_Entries = dimension_size( MySpline ); SPLINE_ENTRY: #declare Float_Time_Parameter = MySpline[ Counter ][ 0 ]; #declare Vector_Value_Of_Entry = MySpline[ Counter ][ 1 ];
With MegaPOV, in every test using Inside of objects the bounding object has now priority. It first tests if the point is inside the bounding. If it is not then it knows that it can already decide that the point is outside (if the object is not inversed) or that the point is inside (if the object is inversed).
This should increase rendering speed of complicated CSG objects, since it could eliminate a lot of computing steps. The inside test is firstly done for the bounding object. Only when this test is inside the bounding, the tests against each of the objects composing the CSG object will be done.
Based on the text enhancement idea of Jamis Buck and Noel Bundy, but modified and extended.
Syntax is:
text { the usual text stuff ... [ h_align_left | h_align_center | h_align_right ] [ v_align_top | v_align_center | v_align_bottom ] }
h_align_left By adding this keyword to the text block, the text string (including horizontal offset) is aligned horizontally so that its most left point touches the y-axis. This is identical to the default alignment.
h_align_center By adding this keyword to the text block, the text string (including horizontal offset) is aligned horizontally so that it extends equally on both sides of the y-axis.
h_align_right By adding this keyword to the text block, the text string (including horizontal offset) is aligned horizontally so that its most right point touches the y-axis.
v_align_top By adding this keyword to the text block, the text string (including vertical offset) is aligned vertically so that its highest point touches the x-axis.
v_align_center By adding this keyword to the text block, the text string (including vertical offset) is aligned vertically so that its middle height sits on the x-axis.
v_align_bottom By adding this keyword to the text block, the text string (including vertical offset) is aligned vertically so that its lowest point sits on the x-axis.
![]() | Note |
---|---|
When no alignment is specified, the POV-Ray™ defaults are used. Horizontally to the left and vertically on the base line. The old keyword "position" of previous MegaPOV versions is no longer supported. |
simcloth allows to simulate cloth in MegaPOV. The cloth patch is rectangular, and interacts with its environment (gravity, some obstructing objects, wind, ...).
Syntax is:
simcloth { [ environment OBJECT-IDENTIFIER ] [ friction FLOAT ] [ gravity VECTOR ] [ wind { PIGMENT } ] [ viscosity FLOAT ] [ neighbors 0 | 1 ] [ internal_collision on | off ] [ damping FLOAT ] [ intervals FLOAT ] [ iterations INTEGER ] input STRING [ output STRING ] [ mesh_output STRING ] [ smooth_mesh on | off ] [ uv_mesh on | off ] }
environment is followed by an object identifier. The object should be declared before simcloth {}. This object defines the environment that will interact with the cloth. Although any object can be used, it is recommended to use objects which have well-defined interiors.
friction is a coefficient specifying energy loss when the cloth touches the environment. A low value (<= 0) means a lot of friction and strongly slows the movement of the cloth. A high value (>= 1) will allow the cloth to slide over the objects (but not to bounce off ...). Default value is 1.0
gravity Specifies the direction and the strength of gravity. The default value is <0, 0, 0>.
wind A pigment is used to define the direction and strength of the wind in every space location. At a given point, the wind is defined by the red, green and blue components of the pigment at this point. You can explicitly declare the pigment, or use an already declared identifier. Don't forget that the color components can take any value you want (negative ones, greater than one, ...)
viscosity Specifies the influence of the wind and air friction on the cloth. The default value is 0 (no influence).
neighbors Specifies the number of neighbors that are joined by springs at each point. neighbors 0 is for 8 neighbors (faster but rougher calculation), and neighbors 1 (default value) is for 24 neighbors (slower calculation, but better results).
internal_collision Activates or deactivates internal collision management (cloth against itself). This problem is handled by added springs between points that are too close together. System instability probability is increased, and you must, most often, decrease the intervals parameter (see below). Deactivated by default (warning: much longer parsing when activated).
damping General energy loss parameter, it limits the accumulation of the model approximations and errors. A value lower than 0.95 (default value) is strongly recommended.
intervals specifies the time interval between each iteration. Keep it low. Default value is 0.05.
iterations It's the number of iterations to calculate.
input Filename of the starting *.cth file. The only required parameter, since you need a cloth to start with. For a complete description of the *.cth file format, see below.
output Filename of the ending *.cth file. If this parameter is specified, the result of the simulation is saved. Useful for animations, or for a multi-stage calculation.
mesh_output Allow the program to output a file (with specified name), containing tons of triangles, corresponding to the cloth points after the simulation. It allows you to save the result of a simulation, in a format usable by other POV-Ray™ versions (official or unofficial).
smooth_mesh Activate or deactivate the creation of smooth_triangle's if the mesh_output option is activated. Deactivated by default.
uv_mesh Activates or deactivates uv coordinates within the triangle (or smooth_triangle) if the mesh_output option is activated. UV coordinates go from <0, 0> to <1, 1>. Deactivated by default.
The file format is simple: the first line describes the cloth dimensions (number of points n1 and n2, normalized length between 2 neighbors nlng), and the springs strength ks. The other lines describe the location in space and velocity of each point. All values (3 for location, 3 for speed) are separated by commas, and each line is terminated by a comma as well.
Then, there are the constraints definitions. Constraints are 3 coefficients (1 for each axis) that will control the velocity vector of a given point of the cloth. It will be possible, for instance, to slow down a corner of the cloth along one axis, to completely stop it along another axis, and let it free along the last one. A constraint is defined by an integer (index), and 3 floating point coefficients, representing the constraint (respectively on x, y, z axis), all this on the same line and separated by commas. The index is the rank of the point (beginning at 0) in order of declaration of the cloth points. Constraints can be declared in any order.
You could see the cloth as 2 arrays of vectors Points[n1][n2], and Velocity[n1][n2], and its constraints Indexn, coefn. The *.cth file will look like this:
n1, n2, nlng, ks, Points[0][0], Velocity[0][0], Points[0][1], Velocity[0][1], ... Points[0][n2-1], Velocity[0][n2-1], Points[1][0], Velocity[1][0], Points[1][1], Velocity[1][1], ... Points[1][n2-1], Velocity[1][n2-1], Points[2][0], Velocity[2][0], ... ... Points[n1-1][n2-1], Velocity[n1-1][n2-1], Index1, coef1[x], coef1[y], coef1[z], Index2, coef2[x], coef2[y], coef2[z], Index3, coef3[x], coef3[y], coef3[z],
For an example of a macro writing such a file (see Section 4.1.1.1.1).
In POV-Ray™ 3.5 the messages concerning the max_gradient follow a heuristic method to be displayed. This means that the message only appears when the difference with the set max_gradient is more than a certain percentage. Also when using a loop with hundreds of isosurfaces which have different max_gradient's, you need to wait after the render for all those messages to be displayed: this can take several minutes. Basically, you cannot control these messages.
In MegaPOV 1.0 you can use the keyword message to control the message flow:
This keyword is used in the isosurface{} block and should be used after the function{} block and before any material.
By using conditional expressions, you can now control messages in a loop.
This atmospheric glow effect makes a fast-rendering glow effect. It is based on the light source glow effect from POV-AFX, written by Marcos Fajardo, but has been heavily modified.
glow { type 0 | 1 | 2 | 3 location VECTOR size FLOAT radius FLOAT fade_power FLOAT color COLOR TRANSFORMATIONS }
You can specify glows individually, or attached to a light_source. If created in a light source, they will be automatically initialized with the light's position and color (though transforming the light source will not give the expected result).
Choose a glow type from 0, 1, 2 or 3. Type 2 and 3 glows are not completely implemented yet, but 2 will be based on the exp() function and 3 will simulate a sphere with constant density.
The size keyword adjusts the scale of the glow effect. It is not an absolute size, just a scaling amount (because some glows are infinite). It does not quite work properly yet, it causes strange effects with changing distances of objects behind the glow.
The radius keyword specifies a clipping radius confining the glow to a circular area perpendicular to the ray. If the glow is still visible at this radius, it will make a sudden transition.
The fade_power keyword allows you to provide an exponent to adjust the falloff with.
![]() | Note |
---|---|
A glow is not an object, it is an atmospheric effect. Therefore glows cannot be used in CSG operations. Transformations on a glow only affect the location vector. So will scale not change the size or shape of a glow, but scale the location coordinates. |
pigment { listed FLOAT color_map { color_map stuff } } | pigment_map { pigment_map stuff } } } normal { listed FLOAT normal_map { normal_map stuff } } }
This "pattern" is simply a solid pattern, the value of FLOAT is used as the return value of the pattern. This means that the pattern listed at the specified FLOAT value is used as the pattern for the whole object.
This is very useful in having a progression of objects blending from one texture to another, and can also be useful in animating textures.
warp { displace { PATTERN | FUNCTION, COLOR_MAP type 0 | 1 } }
Displaces the pattern by an amount determined by the PATTERN or FUNCTION and COLOR_MAP at each point.
In type 0, the rgb values of the pigment at each point are used as xyz displacement amounts.
In type 1, the brightness of the pigment color determines the directions and amounts points are pushed.
pigment { noise_pigment { TYPE, MIN_COLOR, MAX_COLOR } }
TYPE:
Produces a "static" effect. This is a pigment, like an image_map, not a pattern. Anti-aliasing tends to mess it up when used in textures, and it is not animation-safe (unless you want an animated static effect). It can be used in an average map to add some noise to a pigment.
This addition simulates decrease of reactive chemicals in film emulsion during exposure. The areas that have received more light react less than other areas. Useful for high contrast scenes as it brings up the dark areas and limit bright areas.
There are two new keywords in the global_settings block:
exposure FLOAT exposure_gain FLOAT
where exposure_gain is optional and has default value 1. Both parameters have to be greater than 0 to influence rendering.
exposure can be thought as film speed, aperture and exposure time multiplied together. The value is not absolute. If the light source intensities in the scene are multiplied by 10 and exposure value is divided by 10 the resulting image will be the same.
exposure_gain can be used to brighten scenes with low maximum intensity when also low exposure value is used.
The equation for such behavior of color used in MegaPOV is:
color = exposure_gain * (1 - exp( - exposure * color )).
Example 2.7. Various values for film exposure simulations
Examples which map range 0-1 to range 0-1 with increasing amount of compression:
exposure 0.05 exposure_gain 20 // almost linear exposure 0.2 exposure_gain 5.5 exposure 0.5 exposure_gain 2.5 exposure 1 exposure_gain 1.6 exposure 10 exposure_gain 1 exposure 100 exposure_gain 1 // high compression
In POV-Ray™ 3.5 and earlier temporary files with cache of radiosity were named the same for every frame in the animation rendering. Since MegaPOV 1.0 the name of this file is concatenated from the name of the currently rendered image. Together with Frame_Step (see Section 2.1.1) and this addition it is finally possible to start two parallel processes with radiosity rendering over one source.
The mechanics simulation system is integrated into the POV-Ray™ rendering system. The simulation parameters are set in the global_settings{} block of the scene file. While parsing the scene MegaPOV calculates the simulation exactly where it occurs in the file. This way the simulation can interact with the scene by using objects, functions and values set before the mechsim{} block in the scene file. But additionally the simulation data can also be used in the scene later on for placing objects according to the simulation results.
This patch introduces a new block in the global_settings{} section of the POV-Ray™ scene file.
The complete syntax description of this block is:
MECHSIM: mechsim { [MECHSIM_ITEMS...] } MECHSIM_ITEM: method INTEGER | gravity VECTOR | time_step FLOAT | step_count INTEGER | time FLOAT | start_time FLOAT | end_time FLOAT environment { ENVIRONMENT_DEFINITION [ENVIRONMENT_ITEMS...] } | interaction { INTERACTION_DEFINITION ... } | field { FIELD_DEFINITION ... } | attach { ATTACH_DEFINITION ... } | collision { COLLISION_TOGGLE [COLLISION_ITEMS...] } | topology { [GROUP_DEFINITIONS...] [TOPOLOGY_ITEMS...] [save_file FILE_NAME [Type]] } ENVIRONMENT_DEFINITION: function [(IDENT_LIST)] { FUNCTION_ITEMS } | object OBJECT ENVIRONMENT_ITEM: stiffness FLOAT | damping FLOAT | friction FLOAT [, FLOAT] | method INTEGER INTERACTION_DEFINITION: function [(IDENT_LIST)] { FUNCTION_ITEMS } FIELD_DEFINITION: function { SPECIAL_COLOR_FUNCTION } ATTACH_DEFINITION: function { SPLINE } COLLISION_TOGGLE: [INT_MASS_MASS [, INT_MASS_FACE]] COLLISION_ITEM: stiffness FLOAT | damping FLOAT | friction FLOAT [, FLOAT] GROUP_DEFINITION: group [(INT_GROUP_INDEX)] { TOPOLOGY_ITEMS... } TOPOLOGY_ITEM: mass { V_POSITION, V_VELOCITY, F_RADIUS mass FLOAT | density FLOAT [attach INTEGER] [fixed BOOL] } | connection { INDEX1, INDEX2 [stiffness FLOAT] [damping FLOAT] [length FLOAT] } | face { INDEX1, INDEX2, INDEX3 } | load_file FILE_NAME
Some general parameters can be given in the top level of the mechsim{} section.
The default values are:
method : 1
gravity : <0, 0, 0>
time_step : 0.1
step_count : 10
Selects the integration method used for solving the equations of movement.
Possible values are:
Method 1 is a first order integration method also known as explicit Euler method. With the differential equations of movement written as:
dy/dt = f(t, y)
y being the state of the system (positions and velocities) and the initial conditions y(t0)=y0 the Euler method can be written as:
yn+1 = yn + h*f(tn, yn)
Method 2 is a second order integration method known as Heun's method. It's formula is:
k1 = f(tn, yn)
k2 = f(tn + h, yn + h*k1)
yn+1 = yn + (h/2)*(k1 + k2)
Applies an overall constant gravitational force to all masses.
A vector is expected, the unit is m/s².
Standard earth gravity (with y=up coordinates) is:
gravity <0, -9.81, 0>
With field functions (see Section 2.6.3.1.6) non constant gravity can be simulated
All simulation methods use discrete time steps for calculating the simulation. There are three parameters to steer this but only two are needed to correctly define the stepping. The formula for calculating the third is:
Step_Count = Time / Time_Step
An optional start_time value allows to specify a starting time different from 0. Changing this can influence the attach and environment function. (see Section 2.6.3.1.7 and Section 2.6.3.1.2) Specifying an end_time value instead of time is also possible.
![]() | Important |
---|---|
Using too large time steps can lead to instability in the simulation. MegaPOV will recognize this in most cases and stop simulation with an error message but this does not mean the simulation is correct as long as no error is reported. Simulation results should always be checked for plausibility. |
Environments are shapes the simulated masses are supposed to interact with. Several of them can be created with environment{} blocks.
An environment is defined either by a user defined function or an object. If both are given the function is preferred.
Apart from the default parameters (x, y and z) the function can have a fourth parameter supplying a time index. This way moving environment objects can be simulated.
#declare fn_Env=function(x, y, z, tim) { z-tim } global_settings { ... mechsim { ... environment { function(x, y, z, tim) { fn_Env(x, y, z, tim) } ... } } }
There are three parameters defining the properties of the environment:
stiffness The elasticity parameter of the surface. The unit is N/m or kg/s².
damping Depending on the environment calculation method (see below) this is either a diminishing factor (<1) applied to the mass velocities at each collision or a damping constant (unit kg/s)
friction The friction factor controls the amount of friction during collisions. An optional second parameter, the friction excess value should usually be slightly larger than 1 and causes the friction to occur already slightly above the surface. This can be helpful to obtain realistic results.
There are currently two methods how the environment collisions can be calculated:
Method 1 (MECHSIM_ENV_METHOD_FORCE) is force based. When a mass collides with the environment a force is applied in direction of the function gradient (with function based environments) or the surface normal (with objects). The stiffness, damping and friction parameters influence this force. friction defines the ratio between the tangential force and the normal force.
Method 2 (MECHSIM_ENV_METHOD_IMPACT) is based on impact laws. The velocity is inverted at the surface and diminished by the damping factor in normal direction and by the friction value in tangential direction. stiffness does not have any influence in this case.
Since this method directly modifies the velocity rather than applying forces it should only be used with the first order (Euler) integration method.
With the gradient descent simulation method the method parameter does not have any effect.
The collisions referred to here are not environment collisions but collisions between the simulation elements. Since detecting this kind of collision is quite computationally intensive it is turned off by default.
With two numbers at the beginning of the collision{} section collision can be toggled for both mass-mass-collisions and mass-face-collisions. Both parameters are optional, the meaning of the possible values is:
Internal collisions are always calculated with forces. The same three parameters like in the environment settings can be used to specify the properties
The topology{} section is the central part of the whole simulation settings. Here the simulation elements, their positions and properties, can be defined.
There are three topology items: masses, connections and faces. Each of them has several parameters that can be set.
The mass block defines a point mass. These are the central elements of the simulation. Their movement is calculated by the simulation system.
The mass block contains the following elements:
In addition either the mass (unit: kg) or the density (unit: kg/m³) of the element has to be given. If density is specified the resulting mass is calculated automatically. An optional boolean parameter (fixed) prevents the mass from moving if set to true.
A complete example for a mass definition:
mass { <0, 0, 1>, /* position */ <1, 0, 0>, /* velocity */ 0.1 /* radius */ density 600 // mass 2 // fixed true }
The connection block defines a connection between two point masses. It can have elastic and dissipative properties.
The first two elements of this block are integer numbers specifying the indices of the masses to connect.
There are three optional parameters: The stiffness value specifies the elasticity of the connection (unit N/m or kg/s²). damping the velocity proportional damping factor (unit kg/s). The default value for both of these is zero. The third parameter allows to specify a relaxed length of the connection. If it is not specified the distance of the two masses is used for this property.
A complete example for a connection definition:
global_settings { ... mechsim { ... topology { mass { ... } /* mass with index 0 */ mass { ... } /* mass with index 1 */ connection { 0, /* index of the first mass */ 1 /* index of the second mass */ stiffness 10000 damping 2000 // length 0.5 } ... } } }
The face block defines a triangular face between three point masses. It is used for collision calculations (see Section 2.6.3.1.3) and can be useful for generating a mesh from the simulation data for display.
There are three integer numbers in the block, the indices of the masses forming the face.
A complete example for a face definition:
global_settings { ... mechsim { ... topology { mass { ... } /* mass with index 0 */ mass { ... } /* mass with index 1 */ mass { ... } /* mass with index 2 */ face { 0, /* index of the first mass */ 1, /* index of the second mass */ 2 /* index of the third mass */ } ... } } }
Simulation elements can be categorized into groups. The main purpose of this is to speed up collision tests. The group keyword can be followed by an integer number in parentheses to explicitly specify the group. Otherwise the group index is determined automatically.
global_settings { ... mechsim { ... topology { mass { ... } /* these elements are group index 0 */ ... group { mass { ... } /* these elements are group index 1 */ } group { mass { ... } /* these elements are group index 2 */ } group (1) { mass { ... } /* these elements are group index 1 */ } ... } } }
The topology data can be written to and loaded from files. For the format of these files see Section 2.6.3.3.
save_file can only be added to the main topology{} block. It saves the complete data after the simulation to the specified file.
load_file can be placed anywhere in the topology{} section. If placed in a group the elements in the file are added to that group. Otherwise they are are placed in groups according to group index information in the file.
The same file name can be specified for both loading and saving the data. This is especially useful for animation when the following frame simulation should start with the result of the last frame:
global_settings { ... mechsim { ... topology { load_file "mechsim_data.dat" save_file "mechsim_data.dat" } } }
Masses can be set to exert forces on each other depending on the distance and the position in space. Phenomena like gravity in space and electrostatic fields can be simulated this way.
The interaction{} block can contain one or more user defined functions. Apart from the default parameters (x, y and z) the functions can have a fourth parameter that is used for the distance between the masses. The function return value defines the force exerted on both masses in opposite directions. Positive values mean attractive forces and negative values repulsion.
#declare fn_Force=function(x, y, z, dist) { 1/(dist*dist) } global_settings { ... mechsim { ... interaction { function(x, y, z, dist) { fn_Force(x, y, z, dist) } ... } } }
General field like forces can be simulated using the field{} block. One example for such a field force is gravity although the simulation system has a special parameter for specifying such a simple constant gravity force. Much more complicated fields can be set up using this function.
The field{} block expects a pigment function defining the force components in the different directions. The red component of the pigment for the x direction, the green component for the y direction and blue for z. The mechsim include file contains a macro generating an appropriate pigment function from three float functions.
Example 2.9. Constant downward force in Mechanics simulation
A function for a constant downward force (in y direction) would look like:
#include "mechsim.inc" global_settings { ... mechsim { ... field { function { Vector_Function( function {0}, function {-1}, function {0} ) } ... } } }
Note that in contrast to the gravity parameter the fields define a force and not an acceleration. Large masses will be influenced less than small masses.
Apart from adding the fixed flag to masses and thereby fixing them to a certain position we can also constrain them to a certain predefined movement. Those movements are described with spline functions in the attach{} block.
global_settings { ... mechsim { ... attach { function { spline { linear_spline 0.0, <0,0,0> 0.5, <1,0,0> 1.0, <2,0,0> } } } ... } } }
These functions are automatically numbered starting from zero. To attach a mass to a function the attach parameter has to be set in the mass definition. The following mass is attached to the attach function with the number two:
mass { <0, 0, 1>, <0, 0, 0>, 0.1 density 600 attach 2 }
During the simulation the spline is evaluated at the current time value and the returned vector describes the movement of the attached masses. Note that the spline does not describe an absolute position for the masses, just their movement relative to their starting position. Attaching several masses to the same spline makes them perform a parallel movement.
The whole simulation data can be accessed anywhere in the POV-Script. This is achieved by adding new float/vector functions:
The complete syntax description of this block is:
FLOAT_FUNCTION: ... | mechsim : MECHSIM_ELEMENTS MECHSIM_ELEMENTS: mass_count | connection_count | face_count | mass( INTEGER ) : MASS_FLOAT_ELEMENT | connection( INTEGER ) : CONNECTION_FLOAT_ELEMENT | face( INTEGER ) : FACE_FLOAT_ELEMENT MASS_FLOAT_ELEMENT: radius | mass CONNECTION_FLOAT_ELEMENT: index1 | index2 | length | stiffness | damping FACE_FLOAT_ELEMENT: index1 | index2 | index3 VECTOR_FUNCTION: ... | mechsim : MECHSIM_ELEMENTS MECHSIM_ELEMENTS: mass( INTEGER ) : MASS_VECTOR_ELEMENT MASS_VECTOR_ELEMENT: position | velocity
These elements correspond to those set in the mechsim{} block in global_settings{}. The mass position and velocity are the ones that are modified during simulation. The mass_count connection_count and face_count values are especially useful inside the mechsim{} block to determine the current index:
global_settings { ... mechsim { ... topology { /* part 1 */ mass { ... } mass { ... } connection { ... } ... #declare Start_Mass_Part2=mechsim:mass_count; #declare Start_Connection_Part2=mechsim:connection_count; /* part 2 */ mass { ... } mass { ... } connection { ... } ... } } }
The Start_Mass_Part2 and Start_Connection_Part2 variables can later be used to display the different parts of the simulation in different forms.
The file format used by the load_file and save_file options is a text format compatible to the POV-Ray™ #read and #write directives.
The different fields in the file (referred to as elements here) are separated by commas (,) and each contain either a string, an integer or float value or a vector.
The first element is a four character string ('MSIM') identifying the mechanics simulation file format. The second element is an integer number specifying the subformat of the file. Subformat 2 was used in Sim-POV 0.1.0 and Sim-POV 0.2.0 allows to write subformat 2 and 3.
The main difference is that type 3 files contain the attach index (see Section 2.6.3.1.7) for each mass. In addition the subformat value is followed by a float for the start time in subformat 3. When the simulation data is saved after the simulation the time index at the beginning is increased by the simulation duration. This way environments and attachments are correctly moved during animations. The subformat can be specified with an additional number after the file name string in save_file. The default subformat is 2.
The following three integer numbers are the numbers of masses, connections and faces in the file. After them follows the data of all masses, connections and faces in that order.
For each mass there are the following elements:
For each connection:
For each face:
The files written by MegaPOV contain a line break after the subformat value, the mass count, connection count and face count value and after each mass, connection and face.
Example 2.10. The simulation data file format
A short sample file looks like this:
MSIM, 2, 3, 3, 1, <-2, -2, 0>, <0, 0, 0>, 2.0, 0.05, 0, 0, <2, -2, 0>, <0, 0, 0>, 2.0, 0.05, 0, 0, <0, 2, 1>, <0, 0, 0>, 2.0, 0.05, 0, 0, 0, 1, 0.8, 12000, 6000, 0, 1, 2, 0.8, 12000, 6000, 0, 0, 2, 0.8, 12000, 6000, 0, 0, 1, 2, 0,
Table of Contents
This part describes the mechsim.inc include file that comes with MegaPOV and contains various macros simplifying the use of the mechanics simulation features.
The mechsim.inc include file contains several macros so simplify the generation of simulation topologies as well as macros building POV-Ray™ objects representing the simulation data.
At the beginning of the file there are various declarations of textures and other things that are used by the macros. In most cases you can override the default values by declaring the identifiers differently before including the file.
MSIM_INCLUDE_VERSION
The version number of the mechsim.inc include file.
No_Trans
A dummy transform that can be used in the topology generation macros if no transform is supposed to be used.
MSim_File_Decimals
The number of decimal places to be written to files for coordinates. Default value is 12.
MSim_Test_Render
If true reflection is turned off for the textures in this include file. Default value is false.
MSim_Tex_N
Texture to be used for texturing the nodes (masses) of the simulation topology. A grey metallic texture by default.
MSim_Tex_C
Texture to be used for texturing the connections of the simulation topology. A gold metallic texture by default.
MSim_Tex_Mesh
Texture to be used for texturing the faces of the simulation topology. A bluish metallic texture by default.
fn_Stress_CM
Color map function to use for visualizing the stress in simulation topologies. A color (pigment) function is used here. It is evaluated in x-direction between 0 and 1.
POV-Ray™ does not allow to directly define custom vector functions. With pigment functions it is possible to generate a vector function from three float functions though. The way this macro works makes it necessary to have a limited range for the function values. Vector_Function() is a wrapper macro for Vector_Function_Range() using a default range of 1e6. If necessary this can be changed by declaring a different value for MSim_Fn_Range before including mechsim.inc.
The Vector_Function() macro is used the following way:
#declare Fn_Vector= function { Vector_Function( function { x }, function { x*x }, function { 0 } ) }
where the three functions define the return vector's x, y and z components.
The mechanics simulation patch uses vector functions in the field feature (see Section 2.6.3.1.6).
These macros generate POV-Ray™ objects from the simulation data. Currently there are macros for general topology visualization and specific macros for generating meshes from patch topologies created with the patch generation macros.
This macro generates POV-Ray™ shapes for all masses and connections or faces from a certain range of the simulation data.
Depending on the value of the Show_Faces parameter the macro will either generate a union of cylinders and spheres representing the masses and connections or a mesh with triangles representing the faces.
parameters:
Start_Mass_Index, Start_Connection_Index, Start_Face_Index - the starting indices of the range of simulation elements that should be displayed by the macro.
End_Mass_Index, End_Connection_Index, End_Face_Index - the end indices of the range of simulation elements that should be displayed by the macro. If one of this values is <0 all elements until the last one are displayed.
Connect_Rad - the radius to use for the connections. If this value is <0 the macro uses 0.4* the mass radius for this. If this value is 0 no cylinders are generated for the connections.
Show_Faces - if true only a mesh representing the faces is generated. If false connections are represented by cylinders and masses by spheres.
Stress_Fact - if >0 the connections are textured to visualize the stress. The fn_Stress_CM function is used for the colors. The extension from relaxed length is scaled with this factor. If this value is <0 the connections are textured with MSim_Tex_C.
File_Name - file name string. If its length is zero file writing is turned off, otherwise the geometry is written to a file with that name in addition.
Example 3.1. MechSim_Show_Objects() macro usage
show all masses and connections:
MechSim_Show_Objects(0, 0, 0, -1, -1, -1, -1, false, -1, "")
declare an object of all faces
#declare Obj=MechSim_Show_Objects(0, 0, 0, -1, -1, -1, -1, true, -1, "")
show a subset of connections and faces, texture connections to visualize stress, write objects to file:
MechSim_Show_Objects(0, 0, 0, 100, 300, 0, -1, false, 120, "sim01.inc")
Variation of the MechSim_Show_Objects() macro displaying all elements of the current simulation data.
parameters:
Connect_Rad - the radius to use for the connections. If this value is <0 the macro uses 0.4* the mass radius for this. If this value is 0 no cylinders are generated for the connections.
Show_Faces - if true only a mesh representing the faces is generated. If false connections are represented by cylinders and masses by spheres.
Stress_Fact - if >0 the connections are textured to visualize the stress. The fn_Stress_CM function is used for the colors. The extension from relaxed length is scaled with this factor. If this value is <0 the connections are textured with MSim_Tex_C.
File_Name - file name string. If its length is zero file writing is turned off, otherwise the geometry is written to a file with that name in addition.
This macro generates a mesh from the patch topology created with the MechSim_Generate_Patch() macro (see Section 3.1.4.6). The mesh is generated in form of the new mesh2 type and optionally includes uv- and normal data depending on the parameters.
parameters:
Start_Face_Index - the index of the first face that is part of the patch. This should be stored when the patch is generated. The other starting indices are calculated internally.
XSize, YSize - size of the patch, number of nodes in x- and y-direction.
Smooth - if true normal vectors are generated so the mesh is smoothed.
UV - if true uv-coordinates are generated ranging from 0 to 1 in x-Direction (range in y-Direction depends on the ratio of XSize to YSize).
Stress_Fact - if >0 the triangles of the mesh are textured on per vertex basis to visualize the stress. The fn_Stress_CM function is used for the colors. The connection's extension from relaxed length is scaled with this factor. If this value is <0 the whole mesh is textured with MSim_Tex_Mesh.
File_Name - file name string. If its length is zero file writing is turned off, otherwise the geometry is written to a file with that name in addition.
Example 3.3. MechSim_Show_Patch() macro usage
show a 50x50 patch with smoothing:
MechSim_Show_Patch(0, 50, 50, true, false, -1, "")
declare an object for the patch, generate uv coordinates and normal vectors, write the results to a file:
#declare Obj=MechSim_Show_Patch(0, 50, 50, true, true, -1, "sim01.inc")
Here a comparison between the different methods and variations:
These macros are supposed to be placed in the topology{} block of the mechsim{} section. They generate the masses, connections and faces for certain geometries.
Most of the macros have a parameter named Connect_Arr. This is an array containing weighting factors for the different connections in.
The objects generated by the macros have different types of connections: axis-parallel connections, 2D and 3D diagonal connections and possibly bending connections. How these connections are weighted influences the properties of the object and can be controlled by the values in this array. Which value refers to which type of connection depends on the macro and is mentioned in the macro description.
This macro generates 3D rectangular grid of masses with connections and optionally faces on the outside. The density of the masses as well as the stiffness and damping of the connections can be varied with functions.
The generated box starts at the origin and extends in positive x, y and z-direction.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
fn_Density - user defined function controlling the density of the masses. x, y and z are evaluated in [0..1] range.
fn_Stiffness - user defined function controlling the stiffness of the connections.
fn_Damping - user defined function controlling the damping of the connections.
Faces - if true faces are generated on the outside shape.
Cube_Scale - 3D vector controlling the distances in the grid. It defines the size of an elementary cell.
Grid_Size - 3D vector containing the number of masses in all three directions.
Transf - Transform to be applied to all mass positions.
Connect_Arr - Array containing weights for connection stiffness and damping. Meaning of the array fields is described below.
See also Section 3.1.4.1. If the first entry is 0 no connections are generated. The individual entries are used for the following connections. Only connections up to the size of the array are generated.
The following pictures illustrate the different sizes of the array:
Table 3.2. MechSim_Show_Patch() variations
![]() | ![]() | ![]() |
0 (first element zero) | array size 1 | array size 2 |
![]() | ![]() | |
array size 3 | array size 4 |
Example 3.4. MechSim_Generate_Grid_Fn() macro usage
generate a 4x4x4 masses grid with double diagonal connections and increasing stiffness and damping in x-direction.
#declare Con_Array=array[3] #declare Con_Array[0]=1; #declare Con_Array[1]=1; #declare Con_Array[2]=1; #declare fn_Density=function(x, y, z) { 32000 } #declare fn_Stiffness=function(x, y, z) { 1000 + x*1500 } #declare fn_Damping=function(x, y, z) { 2000 + x*1500 } MechSim_Generate_Grid_Fn(<0, 0, 0>, 0.08, fn_Density, fn_Stiffness, fn_Damping, true, <0.4, 0.4, 0.4>, <4, 4, 4>, No_Trans, Con_Array)
This macro generates 3D rectangular grid of masses with connections and optionally faces on the outside. In contrast to the MechSim_Generate_Grid_Fn() macro (see Section 3.1.4.2) the density stiffness and damping values are fixed.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Faces - if true faces are generated on the outside shape.
Cube_Scale - 3D vector controlling the distances in the grid. It defines the size of an elementary cell.
Grid_Size - 3D vector containing the number of masses in all three directions.
Transf - Transform to be applied to all mass positions.
Connect_Arr - Array containing weights for connection stiffness and damping. Meaning of the array fields in described in Section 3.1.4.2.
Example 3.5. MechSim_Generate_Grid() macro usage
generate a 4x4x4 masses grid with double diagonal connections.
#declare Con_Array=array[3] #declare Con_Array[0]=1; #declare Con_Array[1]=1; #declare Con_Array[2]=1; MechSim_Generate_Grid(<0, 0, 0>, 0.08, 32000, 1000, 2000, true, <0.4, 0.4, 0.4>, <4, 4, 4>, No_Trans, Con_Array)
This macro generates 3D rectangular grid of masses with connections and optionally faces on the outside. In contrast to the MechSim_Generate_Grid() macro (see Section 3.1.4.3) all connections all have the same stiffness and damping.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Faces - if true faces are generated on the outside shape.
Cube_Scale - 3D vector controlling the distances in the grid. It defines the size of an elementary cell.
Grid_Size - 3D vector containing the number of masses in all three directions.
Transf - Transform to be applied to all mass positions.
Diagonal - A number controlling which diagonal connections are generated in the grid It corresponds to the array size in the MechSim_Generate_Grid() macro (see Section 3.1.4.3).
Variation of the MechSim_Generate_Grid_Std() macro (see Section 3.1.4.4) where instead of the density of the individual masses the mass of the whole grid is given.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Mass - mass of the whole grid.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Faces - if true faces are generated on the outside shape.
Cube_Scale - 3D vector controlling the distances in the grid. It defines the size of an elementary cell.
Grid_Size - 3D vector containing the number of masses in all three directions.
Transf - Transform to be applied to all mass positions.
Diagonal - A number controlling which diagonal connections are generated in the grid It corresponds to the array size in the MechSim_Generate_Grid() macro (see Section 3.1.4.3).
This macro generates a rectangular patch of masses with connections and optionally faces forming the surface. The masses can be fixed with help of a function
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Faces - if true faces are generated for the surface of the patch.
Rect_Scale - 2D vector controlling the distances in the grid. It defines the size of an elementary rectangle.
Grid_Size - 2D vector containing the number of masses in x and y direction.
Transf - Transform to be applied to all mass positions.
fn_Fixed - user defined function controlling whether the masses are fixed or not. The function is evaluated in the x-y-plane between 0 and 1. If the function value at a mass position is >0 the mass is fixed.
Connect_Arr - Array containing weights for connection stiffness and damping. Meaning of the array fields in described below.
See also Section 3.1.4.1. The following picture shows which entries in the array weight which connections. Only connections up to the size of the array are generated.
Example 3.8. MechSim_Generate_Patch() macro usage
generate a 50x50 patch with bending and shearing stiffness. No masses are fixed.
#declare fn_Fixed=function { -1 } #declare Con_Array=array[3] #declare Con_Array[0]=1; #declare Con_Array[1]=1; #declare Con_Array[2]=1; MechSim_Generate_Patch(<0, 0, 0>, 0.065, 8000, 10000, 0, true, <0.055, 0.055>, <50, 50>, No_Trans, fn_Fixed, Con_Array)
This macro generates a rectangular patch of masses with connections and optionally faces forming the surface. In contrast to the MechSim_Generate_Patch() macro (see Section 3.1.4.6) all connections all have the same stiffness and damping. Also none of the masses is fixed.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Faces - if true faces are generated for the surface of the patch.
Rect_Scale - 2D vector controlling the distances in the grid. It defines the size of an elementary rectangle.
Grid_Size - 2D vector containing the number of masses in x and y direction.
Transf - Transform to be applied to all mass positions.
Connect - A number controlling which connections are generated in the grid It corresponds to the array size in the MechSim_Generate_Patch() macro (see Section 3.1.4.6).
This macro generates a line of connected masses and can be used for simulating things like ropes, chains, etc. The masses of the line can be fixed with help of a function
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Spacing - distance between two neighboring masses.
Count - total number of masses.
Direction - 3D vector defining the direction of the line from the origin.
Transf - Transform to be applied to all mass positions.
fn_Fixed - user defined function controlling whether the masses are fixed or not. The function is evaluated in the x-direction between 0 and 1. If the function value at a mass position is >0 the mass is fixed.
Connect_Arr - Array containing weights for connection stiffness and damping. Meaning of the array fields in described below.
See also Section 3.1.4.1. The first element of the array weights the direct connections between two neighboring masses. Further values in the array weight the more distant connections that introduce bending stiffness to the line. Only connections up to the size of the array are generated.
Example 3.10. MechSim_Generate_Line() macro usage
generate a 10 masses line with bending stiffness. No masses are fixed.
#declare fn_Fixed=function { -1 } #declare Con_Array=array[2] #declare Con_Array[0]=1; #declare Con_Array[1]=1; MechSim_Generate_Line(<0, 0, 0>, 0.09, 8000, 10000, 0, 0.45, 10, <1, 1, 1>, No_Trans, fn_Fixed, Con_Array)
This macro generates a line of connected masses and can be used for simulating things like ropes, chains, etc.. In contrast to the MechSim_Generate_Line() macro (see Section 3.1.4.8) only shortest distance connections are generated. Also none of the masses is fixed.
parameters:
Velocity - vector defining the starting velocity of all masses.
Radius - radius of all masses.
Density - density of the masses.
Stiffness - stiffness of the connections.
Damping - damping of the connections.
Spacing - distance between two neighboring masses.
Count - total number of masses.
Direction - 3D vector defining the direction of the line from the origin.
Transf - Transform to be applied to all mass positions.
Table of Contents
Before launching the simulation, it is initially necessary to create the starting *.cth file. It will contain a fresh cloth with the desired dimensions, normalized distances between points and strength coefficient of the springs connecting the points.
The *.cth format was defined in such manner that it is able to be read and written using the POV-Ray™'s input/output files directives (#fopen, #read, #write, #fclose). One thus will write the following macro:
#macro WriteClothFile(filename, n1, n2, nlng, ks, ht) #debug "\nWriting new cth file\n" #fopen file filename write #write(file, n1, ", ", n2, ", ", nlng, ", ", ks, ",\n";) #local l1 = nlng*(n1-1); #local l2 = nlng*(n2-1); #local st = seed(1234); #local i=0; #while (i < n1) #local j=0; #while (j < n2) #local tempx = -l1/2 + i*nlng; #local tempz = -l2/2 + j*nlng; #local tempy = ht + (-1+2*rand(st))*nlng*0.1; #write(file, tempx, ",", tempy, ",", tempz, ", 0.0, 0.0, 0.0,\n") #set j=j+1; #end #set i=i+1; #end #fclose file #end
After having opened the file (#fopen), the macro writes the first line (#write) which contains the number of points of the cloth patch in two dimensions (n1, n2), the normal distance between all points (nlng), and the strength coefficient of the springs (ks).
Then, the various points are distributed in a rectangle of dimension (nlng*(n1-1)) on (nlng*(n2-1)), parallel with the (xz) plane, and at height ht, centered around y axis. A small amount of noise is added to each point coordinates (rand()). Don't forget to close the file (#fclose)...
So we will define a simple table:
#declare Table = union { cylinder { 8*y, 9*y, 8 } torus { 8, 05 sturm translate 85*y } cylinder { 85*y, 0, 05 } cylinder { 0, 05*y, 4 } }
To check that the simulation does not begin with part of the fabric IN the table, we can create the mesh Nappe, using 0 iterations in simcloth:
WriteClothFile("nappe.cth", 50, 50, 1.8/50, 10, 0.95) simcloth { iterations 0 input "nappe.cth" mesh_output "nappe.msh" uv_mesh on } #declare Nappe = mesh { #include "nappe.msh" uv_mapping texture { pigment { checker color rgb <1, 0.5, 0.2> color rgb <1, 0.8, 0.4> scale <1/10, 1/10, 1/10> } } }
Then, the ground, the walls, a light source, a camera, are added, and we obtain this:
And for that, nothing better than the gravity (-0.4*y). Moreover, the table is rough (and the fabric also), one thus will put the coefficient of friction at 0 (high frictions). As the distance between each point is rather small, one will also take a rather small time interval between each iteration (0.03).
simcloth { environment Table friction 0 gravity -0.4*y, damping 0.9, intervals 0.03 iterations 50 input "nappe.cth" output "nappe.cth" mesh_output "nappe.msh" smooth_mesh on uv_mesh on }
Don't forget to look at the messages window (in Windows & Mac version) or output stream (in UNIX version), to know if the simulation ended OK or not (in case of problems while opening files, lack of memory, etc...).
The starting *.cth file can be calculated only once. By putting the WriteClothFile(...) macro in comments thereafter - or make it conditional for clock off: #if(clock_on=off) macro #end - , each simulation will begin again where the preceding one was stopped.
In order to avoid coincident surfaces, you can reduce very slightly the dimensions of the table, and level up the tablecloth a little...
object { Nappe translate 0.001*y } object { Table scale <0.98, 1, 0.98> texture { T_Wood23 rotate <10, 20, 0> } }
For those who are as I am (i.e. lazy), a complete script is available: nappe.pov
After 50 iterations ...
... 50 additional iterations ...
... and 100 more.
The difficulty in making a good-looking lying cloth is to well position the fabric at the beginning, and to make it so that it tends to gather in a smaller zone than its dimensions.
Once more, we will make it easy: a cube (with rounded edges), lying on the ground:
#declare R = 1; #declare Cube = union { box { <R, 0, R>, <1-R, 1, 1-R> } box { <R, 0, 0>, <1-R, 1-R, 1> } box { <0, 0, R>, <1, 1-R, 1-R> } cylinder { <R, 0, R>, <R, 1-R, R>, R } cylinder { <R, 0, 1-R>, <R, 1-R, 1-R>, R } cylinder { <1-R, 0, R>, <1-R, 1-R, R>, R } cylinder { <1-R, 0, 1-R>, <1-R, 1-R, 1-R>, R } sphere { <R, 1-R, R>, R } sphere { <R, 1-R, 1-R>, R } sphere { <1-R, 1-R, R>, R } sphere { <1-R, 1-R, 1-R>, R } translate -0.02*x } #declare Obstacle = union { plane { y, 0 } object { Cube } }
We will reuse the WriteClothFile(...) macro from the preceding example, and we will create a rectangular cloth patch (30 X 50 points):
WriteClothFile("drape.cth", 30, 50, 2/50, 20, 1.5) simcloth { environment Obstacle friction 0 gravity -.5*y damping 0.9 intervals 0.03 iterations 200 input "drape.cth" mesh_output "drape.msh" smooth_mesh on uv_mesh on } #declare Drap = mesh { #include "drape.msh" uv_mapping texture { pigment { checker color rgb <1, 0.5, 0.2> color rgb <1, 0.8, 0.4> scale <1/10, 3/50, 1> } } }
Well... hu... good, but it is not what is called pretty good-looking lying cloth (this one is rather banal...)
Let's modify the positioning of each point of the cloth, in the macro WriteClothFile(...), by carrying out a rotation of -60 degrees around axis Z, and slightly translating it towards the right, like this:
#local tempx = -l1/2 + i*nlng; #local tempz = -l2/2 + j*nlng; #local vtemp = ; #local vtemp = vaxis_rotate(vtemp, z, -60); #local tempy = ht + (-1+2*rand(st))*nlng*0.1; #local vtemp = vtemp + tempy*y + .2*x; #write(file, vtemp.x, ",", vtemp.y, ",", vtemp.z, ", 0.0, 0.0, 0.0,\n")
One does not forget "to level up" the cloth, and the starting position can be visualized:
And finally, let the nature... well, MegaPOV ... do its job:
For the lazy ones, there is a complete script: drape.pov
The fabric starts lying...
Some iterations further...
... and the result.
Obviously, the absence of internal test of collision (fabric against fabric) causes some "errors" (see in bottom of cloth)... . But, one can nevertheless obtain more or less satisfactory results.
This part of the MegaPOV documentation gives a short practical introduction into using the mechanics simulation patch and describes some simple simulations step by step.
The simplest thing that can be simulated with the mechanics simulation patch is the movement of individual point masses. Their movement under the influence of gravity and environment objects is handled in this part.
We start with a simple scene setup:
To simulate the movement of a single mass we add the following to the global_settings{}:
mechsim { gravity <0, 0, -9.81> method 1 environment { object plane { z, 0 } damping 0.9 friction 0.3 method 2 } #if (clock_on) step_count 300 time_step (1/30)/300 topology { load_file "tut02.dat" save_file "tut02.dat" } #else step_count 0 topology { mass { <-2.8, -8.0, 0.9>, <2, 5, 0>, 0.1 density 5000 } save_file "tut02.dat" } #end }
The purpose of the individual lines of this block is the following:
gravity <0, 0, -9.81> activates a standard gravity force in negative vertical direction.
method 1 selects simulation method 1 (Euler integration).
The environment {} block contains the definition of the environment. It contains:
object plane { z, 0 } - the environment object, a plane like seen in the image.
damping 0.9 - a damping factor decreasing the velocity perpendicular to the surface to 90% during every collision.
friction 0.3 - a friction factor decreasing the velocity tangential to the surface by 30% during every collision.
method 2 - activates method 2 collision calculation (impact law based collision).
What follows is an #if conditional. It switches between two different blocks of code depending on whether the scene is rendered as an animation or not. This is useful for initializing the simulation.
The first part contains statements for the animation render:
step_count 300 - makes MegaPOV calculate 300 simulation steps per frame.
time_step (1/30)/300 - sets the duration of each step appropriate for a 30 fps animation.
Finding the right step size is probably something most difficult for the beginner. A smaller step size generally leads to more accurate results. Usually the step size has to be below a certain value depending on the other simulation settings to get usable results, but it is not always obvious if some strange result is due to large time steps. High stiffness values in environments, collision and connections usually require smaller time steps. If you experience unexpected results it is often worth trying to decrease the step size and see if problems vanish.
The topology{} block contains just load_file and save_file statements referring to the same file. This makes MegaPOV load the old simulation data at the beginning, calculate the steps for the current frame and save to the same file afterwards.
The second part contains statements for the still render
step_count is set to zero here so no simulation steps are calculated.
The topology{} block contains a singular mass{} section now. It contains:
<-2.8, -8.0, 0.9> - the starting position of the mass.
<2, 5, 0> - the initial velocity of the mass.
0.1 - the radius of the mass.
density 5000 - the density of the mass (in kg/m³).
The load_file statement finally saves this mass to a file.
To show the mass in the scene we can use a macro from the mechsim.inc include file:
#include "mechsim.inc" MechSim_Show_All_Objects(-1, false, -1, "")
The meaning of the parameters of this macro is described in Section 3.1.3.2.
Now all we need to do is render the scene once as a still to generate the initial data file and afterwards render it as an animation:
In the first part of the tutorial we have handled masses and their movement under the influence of gravity and the constraints of the environment. If several masses exist in the simulation collisions between them have to be taken into account.
For turning collision calculation on the following block is added to the mechsim{} section:
collision { 1, 0 stiffness 60000 damping 3000 }
The first two numbers tell MegaPOV which collision to calculate. For details see Section 2.6.3.1.3. The numbers used here turn calculation on for all mass-mass collisions.
stiffness (unit kg/s²) and damping (unit kg/s) influence how the masses interact.
Another change made in this tutorial step is changing the environment to function based calculations. This usually leads to more accurate environment collisions, especially with more complex geometries but also tends to be slower and requires smaller integration steps.
Defining the environment as a function is fairy easy with the IsoCSG library. The definition in this case looks like:
#include "iso_csg.inc" #declare fn_Env= IC_Merge5( IC_Plane(z, 0), IC_Box(< 1.7,-1.7,-1.0>, < 1.5,1.7,0.5>), IC_Box(<-1.7,-1.7,-1.0>, <-1.5,1.7,0.5>), IC_Box(<-1.7, 1.7,-1.0>, <1.7, 1.5,0.5>), IC_Box(<-1.7,-1.7,-1.0>, <1.7,-1.5,0.5>) )
Note that the stiffness, damping and friction parameters in the environment now have the same meaning as in the collision settings because it uses calculation method 1 (force based environment collisions).
This scene also adds new masses during the animation. This is achieved by adding the following code to the topology{} section:
#if (mod(frame_number, 6)=5) mass { < 1.3,-1.55,0.8>, <-0.2, 5, 0>, 0.18 density 5000 } #end
It means that in every sixth frame a new mass is added at the starting position with the same starting velocity as the first mass.
Apart from masses there is another element that can be added to the topology{} section: connections. Connections can be seen as springs. They connect two point masses and exert a force on them depending on the current distance of the masses compared to the relaxed length of the connection. In addition there is a damping property generating dissipative forces.
A connection{} block is added to the topology{} section like a mass:
connection { 0, 1 stiffness 50000 damping 2000 }
It contains:
0 - the index of the first mass connected.
1 - the index of the second mass connected.
stiffness 50000 - the stiffness of the connection (unit kg/s²).
damping 2000 - the damping of the connection (unit kg/s).
if no length is given the current distance of the masses is used.
The mass indices are counted in order of creation starting at zero. The three connected masses from the following scene are created with:
topology { mass { <0, 0, 2.4>, <0, 0, 0>, 0.1 density 5000 fixed on } mass { <1, 0, 2.4>, <0, 0, 0>, 0.1 density 5000 } mass { <2, 0, 2.4>, <0, 0, 0.6>, 0.15 density 5000 } connection { 0, 1 stiffness 50000 damping 2000 } connection { 1, 2 stiffness 50000 damping 2000 } }
The fixed on in the first mass definition fixes the position of this mass.
With plenty of such connections we can form more complex shapes. The mechsim.inc include file (see Section 3.1) contains several macros forming grids of masses and connections.
Placing the following in the topology{} section generates a box-like grid of connected masses:
MechSim_Generate_Grid_Std( <0, 0, 0>, 0.07, 25000, 22000, 2000, true, <0.4,0.4,0.4>, <3, 12, 3>, Trans1, 3 )
The meaning of the different parameters is described in Section 3.1.4.4. Trans1 is a transform moving the whole grid from its predefined position. It has to be declared before:
#declare Trans1 = transform { translate <-0.5, -6*0.4, 1.0> }
The resulting animation shows a moving and deforming box geometry.
The MechSim_Generate_Grid_Std() macro also generates faces for the outside surface of the box. Faces are triangles each connecting three masses. They can be used for collision calculations and for displaying the geometry as a mesh. The latter can be done easily by changing the parameters of the MechSim_Show_All_Objects() macro:
MechSim_Show_All_Objects(-1, true, -1, "")
Apart from 3D grids we of course can also create 2D rectangular patches. Such objects behave like cloth or foil and offer a very interesting field of simulation.
Like 3D grids rectangular patches can be created with macros from the mechsim.inc include file (see Section 3.1):
MechSim_Generate_Patch_Std( <0, 0, 0>, 0.03, 8000, 10000, 0, true, <0.055, 0.055>, <50, 50>, Trans1, 2 )
This creates a 50x50 masses patch, again movable with a transform. Description of the parameters can be found in Section 3.1.4.7.
The following sample scene also uses a different simulation method than the previous scenes. It is called gradient descent method. It does not integrate the equations of movement like the other methods but moves the masses directly according to the forces influencing them. Inertia does not have effect with these method, therefore oscillations can't occur. Still the step size has to be chosen small enough for accurate results. The movement won't look very realistic in an animation but the final result can be used for a still render. Another disadvantage is the lack of friction, therefore the patch slides off the sphere in the end.
There is also a specialized macro for generating a mesh from a patch topology including normal vectors and uv coordinates. Rendering the previous topology with this macro results in the following picture:
There are a lot more aspects of the mechanics simulation patch that are not handled in this tutorial yet. Reading the reference (see Section 2.6.3) and mechsim.inc include file documentation (see Section 3.1) should help learning about those things. The sample scenes show several examples what the simulation system can be used for but there are a lot more possibilities.
Table of Contents
With increasing raytracing experience and knowledge about algorithms you may want to change/fix some features or add new ones to the core sources of POV-Ray™ or MegaPOV. You may also want modify sources when you want to move a slowly parsed SDL macro to faster C/C++ code within POV-Ray™.
The following section is our effort to write down the conclusions we made from our experience in writing patches compatible with POV-Ray™ architecture with portable documentation and merging those made by others. If you are new to POV-Ray™ or patch writing you should bear in mind we have a long term experience with POV-Ray™ and you probably can learn something useful from the things written here. If you are an experienced patch writer do not hesitate to vary the rules where you think this is appropriate.
Working with sources of POV-Ray™ 3.5 or MegaPOV requires some basic knowledge about:
POV-Ray™ and MegaPOV sources can be considered as a nice lesson in programming and raytracing however do not try to modify sources without basic understanding of the above things. Please, do not waste time asking for detailed explanations when answer seems obvious in the above categories. Try to find some online tutorials or just buy a comprehensive book. Below information is gathered mainly to highlight POV-Ray™ source specific aspects.
Sources of MegaPOV are based on the POV-Ray™ sources distributed officially by POV-Team™. The basis for the modifications included in MegaPOV 1.0 is the source of the 3.5a windows version. Filenames usually well explain the usage. Most files also contain a simple description at the beginning. Each *.cpp filename is delivered with appropriate *.h header file.
All files located in the /source directory in the archives can be considered as part of the following categories:
Switches to enable features of MegaPOV:
Features introduced in MegaPOV:
Common structures and definitions:
Object definitions:
Lighting and other "visible" effects:
Radiosity:
Texturing:
Raytracing helpers:
Builded benchmark:
Math helpers with operation on different types of data:
Parser routines:
IO routines for various formats:
Functions Virtual Machine implementation together with internal functions:
Rendering process:
general program routines, options parsing, text output and other stuff:
As mentioned above the config.h configuration file is located in a platform specific directory. This directory is usually named like the target platform (like windows, dos etc.). There are also other files located in that directory: implementation of GUI, binary resources (like icons), implementation of some (protected) IO operations and other platform specific solutions.
It is hard to describe good guidelines for patching POV-Ray™. Every programmer has own habits and methods including indention, placing of braces, inserting white spaces, favorite naming scheme. But there are some common rules POV-Ray™ patch writers usually follow. Here is our effort for a brief summary - mainly meant as a starting aid for beginning patch writers.
Usually, people put something like #define MY_PATCH in a commonly used file:
Now you should enclose all patch-specific code in #ifdef ... [#else ...] #endif blocks, so removing (commenting) /* #define MY_PATCH */ causes compilation without your patch, and the modifications you make are clearly visible. Optional #else ... is suggested when you are making replacement for existing code (i.e. for bug fixes).
The most common system for patch naming are uppercased words separated with underscores. Names are usually concatenated with word PATCH somehow. In world of Apple mixed case variable names without underscores like MyPatch are also popular.
Example 5.1. Typical patch markup
patches.h:
... #define FAST_SQR_PATCH ...
some_file.cpp:
... #ifdef FAST_SQR_PATCH // new code Value = sqr( Parameter ); #else // old code Value = Parameter * Parameter; #endif ...
Some additions can be also compiler specific changes required by lack of some builded C function or different naming. In such cases you can use predefined compiler specific macros together with your own markup. Each compiler delivers several predefined macros (see Section 5.2).
#ifdef __DJGPP__ // some compiler specific code #else // code for other compilers #endif #if defined( __WATCOMC__ ) && defined( MY_PATCH) // code here #end
Of course it is a little bit more work to maintain changes this way but on the other hand it is also much more readable and allows to prepare two binaries for comparison. It is also much more easier to port your changes into other compilations like MegaPOV then.
Apart from the markup it is important to keep modifications portable. Patches using compiler specific features or functions from a proprietary library won't make it into a patch collection like MegaPOV.
When you add new elements to the POV-Ray scene description language it is a good idea to keep it consistent with the existing syntax. Even if you think a certain syntax would be much easier to use it is very likely to cause much confusion for the user when it differs from existing similar functions.
Some useful information about portability aspects can be found on http://predef.sourceforge.net/.
If you are unsure about a certain aspect of your patch implementation better ask (see Section 1.5.3).
Once a patch is finished you may want to share this patch with the POV-Ray™ Community. Doing this in a wise way can make your patch popular and included in other unofficial custom compilations like MegaPOV is. So before you upload your changes somewhere first check if:
When your modifications are validated then it is time to publish it. There are some common methods in publishing patches:
It is hard to tell which method is the best. The choose of particular method depends on free time, complexity of changes and used sources.
Making binaries from POV-Ray™ and MegaPOV requires:
libraries for linking:
If you have all of this you can try to make your own binaries.
To compile MegaPOV on Windows systems you do not need to buy expensive compilers. There are some free C++ compilers available.
www.borland.com
creation of Windows GUI tested
http://www.borland.com/products/downloads/download_cbuilder.html
included with binaries in basic form, extended documentation for full commercial version at ftp://ftp.borland.com/pub/bcppbuilder/techpubs/b5std.zip
http://groups.google.com/groups?group=borland.public.cpp
__BORLANDC__
http://news.povray.org/povray.binaries.utilities/27877/
http://www.delorie.com/djgpp/
creation of command line version for DOS tested
http://www.delorie.com/djgpp/zip-picker.html
http://www.delorie.com/djgpp/doc/
http://groups.google.com/groups?group=comp.os.msdos.djgpp
__DJGPP__
The core of DJGPP is the MS-DOS port of the GNU C/C++ compiler, GCC, and auxiliary utilities, such as assembler, linker, librarian, Make, and a hypertext docs browser. So people familiar with GCC family should not have problems in using it.
http://www.mingw.org/
command line version for Windows tested
http://prdownloads.sourceforge.net/mingw/
http://www.mingw.org/docs.shtml
http://www.mingw.org/lists.shtml
__MINGW32__
There is name conflict between BLOB and other identifiers in POV-Ray™ and MinGW.
MinGW can be used together with Cygwin, see http://www.mingw.org/mingwfaq.shtml#faq-usingwithcygwin.
An adapted source code package for compiling with MinGW is available on the MegaPOV site.
http://www.cygwin.com/
creation of command line version for windows tested
http://www.cygwin.com/download.html
http://cygwin.com/docs.html
http://cygwin.com/lists.html
__CYGWIN__
With Cygwin you can compile both executables using the Cygwin emulation DLL or not (using the -mno-cygwin flag). Both tested, compilation with X display possible (when XFree86 is installed).
http://www.digitalmars.com/
command line version for windows tested
ftp://digitalmars.com/dmc.zip
ftp://ftp.digitalmars.com/Digital_Mars_C++/Doc/
news://news.digitalmars.com/ , http://www.digitalmars.com/drn-bin/wwwnews?newsgroups=*
__DMC__
there is no atof in standard libraries so it requires to define LACK_OF_ATOF_IN_DMC_PATCH
there is no inversed hyperbolic functions so it requires to define NEED_INVHYP
there is no unlink in standard libraries so it requires to define DELETE_FILE as remove
http://www.openwatcom.org
windows dedicated but non version tested yet
http://www.openwatcom.org/download/download_licenses.html
http://www.openwatcom.org/support/reference_content.html
http://www.openwatcom.org/support/newsgroups_content.html
__WATCOMC__
there are some problems in STL port so this compiler was not forced to correctly compile POV-Ray™ yet, however its move to open source project makes its future
currently available patch 11.0c version is supposed to be an upgrade but can be installed without previous version
http://www.metrowerks.com
Apple Macintosh PowerPC Carbon and Classic versions tested. Windows not tested but possible.
http://store.metrowerks.com/
http://www.metrowerks.com/MW/Develop/Desktop/Macintosh/Default.htm
http://www.metrowerks.com/MW/Support/Newsgroups/default.htm
__MWERKS__
currently available update 8.3
http://developer.apple.com/tools/projectbuilder/index.html
no versions have been ported to Project Builder yet.
http://developer.apple.com/macosx/
you have to join ADC to be able to download. membership however is free.
http://developer.apple.com/macosx/gettingstarted/index.html
http://www.lists.apple.com/mailman/listinfo/projectbuilder-users#Subscribe
?
you need this package in order to build Darwin (UNIX) binaries.
Compiling on Unix systems using the GNU C/C++ Compiler (gcc) and GNU make should be fairly easy. There is a Unix source code package available on the MegaPOV site.
For compiling with graphics display support you need the X and VGALib headers and libraries:
Detailed explanation on how to compile without graphics display support and other specialities is given in the source code package. Compiling with other compilers than gcc should be possible but requires manual modifications in the makefiles.
http://gcc.gnu.org/
ix86 Linux tested, Windows (Cygwin/MinGW) tested, Others not tested but possible.
http://gcc.gnu.org/install/binaries.html
http://gcc.gnu.org/onlinedocs/
http://gcc.gnu.org/lists.html
__GCC__
Tested with gcc 3.1.1 and 3.2.1
Whatever is changed in POV-Ray™ sources, it is probably that new keywords to the parser have to be added. To call your new keyword as NEW_KEYWORD_TOKEN we have to open parse.h and find enumerated tokens within TOKEN_IDS. Entries in this list are sorted mostly by usage.
enum TOKEN_IDS { ABS_TOKEN = 0, : : #ifdef USAGE_WITH_NEW_KEYWORD_PATCH NEW_KEYWORD_TOKEN, #endif : : };
Once integer identifier is added we have to connect NEW_KEYWORD_TOKEN with string for proper parsing. This connection is realized via Reserved_Words array in tokenize.cpp.
RESERVED_WORD Reserved_Words[LAST_TOKEN] = { {AA_THRESHOLD_TOKEN, "aa_threshold"}, : : #ifdef USAGE_WITH_NEW_KEYWORD_PATCH {NEW_KEYWORD_TOKEN, "new_keyword" }, #endif : : };
![]() | Important |
---|---|
Placing of entry into Reserved_Words table in tokenize.cpp does not require any special order, but adding integer identifier into TOKEN_IDS structure in parse.h is connected with type of data returned by usage of added keywords. They have to be located in following order: enum TOKEN_IDS { /* tokens to be used when float value is expected from here */ ABS_TOKEN = 0, ATAN_TOKEN, : FLOAT_FUNCT_TOKEN, /* tokens to be used when vector value is expected from here */ VAXIS_ROTATE_TOKEN, : VECTOR_FUNCT_TOKEN, /* tokens to be used when color value is expected from here */ ALPHA_TOKEN, : COLOUR_KEY_TOKEN, /* other tokens from here */ : /* LAST_TOKEN has to be the last */ LAST_TOKEN };
|
Since years there was a polynomial solver builded in the POV-Ray™ sources. Unfortunately this tool was only for the intersection calculations in the raytracing engine. My idea was to create a gate between SDL and this existing solver.
All changes required for this feature are marked with POLYNOMIAL_SOLVER_PATCH
The polynomial solver in SDL was designed only as a gate to an already implemented feature. It was used previously only for the intersection point. Every next intersection point is almost always different from the previous one because it is calculated with different polynomial equations. In the case of the polynomial solver accessed via SDL in its proposed form it is possible that it is called several times: first for the number of roots and next for each root. That's why before the access to old solver polynomials are cached now (only for SDL usage). This is done with the function buffered_polynomial_solver() in the polysolv.cpp file. The whole change was splitted into three parts:
The complete operations within classic POV-Ray parser was placed inside Parse_Num_Factor() in express.cpp. The order of polynomial is read from the number of parameters there and then buffered_polynomial_solver() is called.
In case of VM in function engine this was a much more difficult operation. n_roots and nth_root have variable number of parameters. It is different than other functions works and it required new handling. First new entries were added at beginning of POVFPU_Opcodes structure in fnpovfpu.cpp. Then a gate between parser and precompiled opcodes was introduced to FNCode::compile_call in fncode.cpp with appropriate calls to dedicated compilers for new functions. Finally runtime code for new opcodes was added to POVFPU_RunDefault in fnpovfpu.cpp.
DocBook is a set of definitions (DTD) for either XML and SGML languages particularly well-suited for books and papers about computer hardware and software.
Its over ten years long history proved its flexibility and usability in many projects. In particular DocBook is used in O'Reilly, xfree86, GNOME, KDE, FreeBSD, The Linux Documentation Project, PHP...
DocBook format is platform independent, concerned on meaning and different parts can be developed independently so since MegaPOV 1.0 DocBook is also used for the MegaPOV documentation. Usually features included in MegaPOV are included in whole package together with original documentation delivered by the author of a particular patch. It would speedup MegaPOV creation if the authors of patches could deliver their documentation in DocBook format. Such documentation is free from decoration, Java Script effects and other additions. Following chapter is filled with guidelines for those authors who want to speedup our documentation creation. Our experience can also help you to create your own documentation for other projects.
Before you will start work with DocBook it could be good to make review on:
to recognize features of DocBook and its syntax. No doubts it is much easier to play with DocBook when you have some HTML experience.
To work with DocBook you have to setup your environment for it. First thing you may be interested is definition of DocBook (DTD). MegaPOV uses XML (http://www.oasis-open.org/committees/docbook/xml/4.2/docbook-xml-4.2.zip) version because SGML one will be dropped in the future.
In order to get good environment you have to collect tools for:
validating:
In case of MegaPOV XMLVALID because it seems the most stable and fastest but it is available only for Windows console.
XSLT processing and converting into other formats:
In case of MegaPOV either XSLTPROC and SAXON are used. In case of PDF output also FOP (http://xml.apache.org/fop/) was used.
Other free XML tools can be found at http://www.garshol.priv.no/download/xmltools/.
You do not need any special tool to edit DocBook files. Any text or HTML editor is enough. Some editors has some support for XML files (like Win-POV) however it is not required.
For simple examples of DocBook files please look at:
It is not purpose of this documentation to describe how DocBook document should look like however in order to get better understanding of DocBook syntax complete sources of this documentation are available within MegaPOV site.
For simpler usage book.xml introduces set of entities with:
Maintaining it that way makes editing easier because we can then simple change markup for all tokens in all places editing only one file. Also patch writer can use those entities to make it easier to connect various documentations from various patch writers into one documentation.
In order to convert DocBook documentation into different formats you need ready for use style-sheets and templates available within http://docbook.sourceforge.net/projects/xsl/ repository. They delivers XSLT files to perform conversion into several formats. Conversion achieved this way is not perfect because authors can't decide what is your favorite appearance of documentation. You have to use so called "customization layer" over their files. MegaPOV has own customization layer. You can find it (*.xsl) where whole sources of documentation are.
Table of Contents
Here is set of appendices
As long as we have to cooperate we can call ourselves The Team. So let's enumerate ourselves :-)
Table 6.1. Current MegaPOV-Team Members
NAME | PARTICIPATION |
---|---|
Linux and Win32 console binaries, developer, documentation | |
Win32 GUI binaries, good soul | |
dos binaries, developer, documentation | |
samples, documentation | |
Mac binaries, developer, documentation |
![]() | Important |
---|---|
Remember! We are not the authors of the POV-Ray™ package. POV-Ray™ was made and is maintained by the POV-Team™. Do not bother them about MegaPOV features and do not ask us about POV-Ray™ itself. |
It would be impossible to create MegaPOV without the outstanding amount of work of all contributors listed below:
christophe.bouffartigue@nanterre.marelli.fr
http://www-public.tu-bs.de/~y0013390/
http://home.earthlink.net/~cjameshuff/
Nathan@Kopp.com
vkrouverk at starman.ee
http://www.profitsoftware.ee/fv/vkhomep.nsf/
pokorny at attglobal.net
mriser@gmx.net
http://www.abx.art.pl/pov/patches/
http://users.skynet.be/smellenbergh/
Here is history of old MegaPOV listed for historical reasons and to highlight community character of this software.
jberger at ifrance com
http://www.stolaf.edu/people/brownen/wwwroot_new/research/index.html
-
-
Daniel_fenner@web.de
jl@artcom-gmbh.de
-
noo@uni-jena.de
http://www2.fwi.com/%7Eparkerr/traces.html#objbound#objbound
ansgar.philippsen at gmx net
-
davidsharp@rcn.com
darenw@pipeline.com