CephaloPOV v0.0.4α
User's Manual

Introduction

CephaloPOV is a JavaScript scripting engine for POV-Ray. It is implemented as a Node command line program that loads a user program and executes it in an environment in which it can manipulate various JavaScript classes that map to POV-Ray's native objects, in addition to having full access to the Node ecosystem. CephaloPOV takes care of generating POV-Ray Scene Description Language files, both for static scenes and multi-frame animations.

The documentation as it stands is more or less complete as far as CephaloPOV itself is concerned, but the longer-term goal of being self-sufficient without requiring familiarity with POV-Ray is still distant.

Table of Contents

What you need (and don't need) to know

One of the major design goals of CephaloPOV is to be accessible to anyone who has basic competency in JavaScript without requiring prior experience with POV-Ray or having to know its Scene Description Language (SDL). However, POV-Ray is an enormous program with a vast array of features, and it will be quite some time before this manual is a complete substitute for POV-Ray's own extensive documentation. In the meantime, POV-Ray novices should refer to the official documentation.

Having said all that, another major design goal of CephaloPOV is to interoperate as smoothly as possible with SDL. You can use existing SDL code with (and within) CephaloPOV JavaScript code, and it is easy to go the other way, incorporating the output of CephaloPOV scripts into SDL.

As far as JavaScript expertise goes, you can get by with a basic knowledge of the language. CephaloPOV uses ES6 classes instead of bare prototypes for most things, but unless you intend to extend them, you can treat them just like prototypes. If you're a JavaScript expert, you can of course do much more than a beginner, but that is a simple matter of programmer skill and not a matter of CephaloPOV's API. All that said, it's worth being very clear that CephaloPOV does not run in your browser; it runs under Node.js. To get very far, you'll need at least minimal knowledge of writing and running programs with Node.

POV-Ray is a non-interactive 3D graphics program, so knowledge of analytic geometry will always be to your advantage, but both POV-Ray and CephaloPOV are designed to be usable to anyone who understands three-dimensional Cartesian coordinates. In the future, CephaloPOV will offer a sophisticated but easy-to-use geometric query system that will let you leverage quite complex math without having to understand the details, but that's still a ways off.

Installation

CephaloPOV is packaged as a Node module. If you don't already have Node installed, take care of that first. Then, using the Node package manager npm, which was installed with Node, you can install CephaloPOV. Open a terminal window -- on Windows systems, you'll want to launch the "Node.js command prompt" -- and type the following command:

$ npm install cephalopov --global

Boom. That's it. Henceforth, you can type cpov at the command prompt to start CephaloPOV.

If you want copies of the examples used in the tutorials and some tools for hacking CephaloPOV's internals, you'll need to get the cpov_examples package from GitHub here. (You can also get the repo used to build CephaloPOV and the npm package but you don't need it to use CephaloPOV or to run the examples.)

Configuration Files

CephaloPOV has a lot of settings, the majority of which live in two objects, cpov.globalSettings and cpov.imageOptions. You will likely find that there are parameters you want to set nearly all the time and a smaller group of parameters that you want to set for a specific project. Fortunately, CephaloPOV supports configuration files that will take care of this for you if you don't mind taking the time to set them up.

There are two (on Windows) or three (on Linux and other Unix clones) configuration files that CephaloPOV consults before it runs the user program. The first of these, /etc/cpov/config.js, is Linux-only. Note that CephaloPOV does not create either the /etc/cpov or its config.js file for you. You'll have to do this using sudo. The following commands will create the directory and an empty config file:

$ sudo mkdir /etc/cpov $ sudo touch /etc/cpov/config.js

Then just open your editor and put the following into config.js:

var config = { imageOptions: { }, globalSettings: { }, settings: { }, }; module.exports = config; // Don't forget this!

Now you have a global config file that does nothing whatsoever! You'll add parameters to the cpov.imageOptions, cpov.globalSettings, and cpov.settings objects that will be copied to their equivalents inside of CephaloPOV at runtime. (For more details, see the Global Parameters section.) One thing worth noticing here is the last line in the config file, module.exports = config;. It's just an ordinary Node module.

There is also a per-user config file that is loaded after the global config file. On Linux and other Unix-like systems, it is named .cpov and appears in your home directory, e.g., ~/.cpov. On Windows, it is located at C:\Users\username\cpov\config.js, where username is, of course, your username. For now, just put a copy of your empty global config file here.

Finally, there is a per-project config file. It is located in the same directory as your user program and is named programName.config.js, so if your program is named prettyPictures.js, its config file will be named prettyPictures.config.js.

To make sure any or all of these files are being loaded correctly, run CephaloPOV with the -vv switch, and you'll see something like this:

$ ./cpov.js -i illus.js -vv [cpov.configLoad] INFO: Failed to load global config file \etc\cpov\config.js [cpov.configLoad] INFO: Successfully loaded and applied user config file C:\Users\eodell\cpov\config.js [cpov.configLoad] INFO: Failed to load project config file D:\prog\cephalopov\illus.config.js

This tells me that I don't have a global or project config file, but it found my user file and loaded it successfully.

The config files are loaded in the order given above, i.e., global, user, project, and if the same parameters are set in each, later files override earlier files. Note that none of these files are necessary, but they can be convenient for some working styles. If you prefer to keep everything self-contained, you can just set parameters inside cpov.imageOptions and cpov.globalSettings in your main program file.

Getting Help

Aside from this documentation, there are three mailing lists for CephaloPOV users. All three are hosted at Google Groups, so you can participate via the web as well as by email:

Should you find a bug, you can report it at the CephaloPOV repo on GitHub.

Tutorial

This section will take you step-by-step through learning how to use CephaloPOV and all its features. It will be, sadly, likely the last section to be completed.










Reference

The reference section contains a complete summary of the CephaloPOV API.










Documentation Conventions

Code and literals in body text are distinguished by the use of a fixed-pitch font. Blocks of code appear in boxes like the one below:

cpov.primitiveDefIdentifier = function(obj) { var result = [ ]; result.push("#" + obj.serial); if(obj.id !== null) result.push(obj.id); return result.join(":"); }

Most tables of object attributes have a standard set of columns:

  1. The first (unlabeled) column specifies the read and write permissions of the attribute, RO for read-only or RW for read-write.
  2. Req: Indicates whether the field is required using Y or N. This is left blank for read-only attributes.
  3. Name: Gives the name of the attribute. This is left unqualified in object class descriptions, but where the global cpov object is described, it is given in full, e.g., cpov.currentFrame.
  4. Type(s): Lists the type or types accepted by the setter function. This is usually a single type, but if multiple types are accepted, they will be listed one after the other.
  5. Description: Contains the full details you'll need to use the attribute, including default values, if any.

API Conventions

Naming

To make things easier for experienced POV-Ray users, the snake_cased names of objects and properties in SDL, with a few exceptions (mostly truncations), are converted directly into the camelCased names which are the norm in JavaScript. Class names begin with a capital letter, so julia_fractal becomes JuliaFractal.

Type Discipline

To avoid making the user painfully debug cases where CephaloPOV accepts an erroneous value and writes it into the SDL output files, CephaloPOV imposes a stricter type discipline than the default JavaScript type system:

Type Indiscipline

The type discipline that CephaloPOV imposes is useful from the standpoint of avoiding careless bugs, but it is only enforced upon static data. In almost every case, object parameters in CephaloPOV can be replaced with either JavaScript callback functions or SDL functions.

SDL functions are specified as strings beginning with "&". (The leading ampersand is stripped off before output.) CephaloPOV presently has no way of determining the validity of SDL code, so you'll need to know exactly what you're doing. This also means that CephaloPOV can't use SDL functions in its internal calculations. For example, if you assign an SDL function returning a vector to an object parameter, that object cannot be transformed within CephaloPOV.

JavaScript parameters are somewhat easier to deal with. Each callback is called as needed with the global cpov object and the object it belongs to, e.g.:

yourFunction(cpov, obj);

On the receiving end, getting the return type right is left to the user as CephaloPOV does not perform any validation tests upon it. CephaloPOV may also call user functions at any time, so they should not have any side-effects or internal state. Unlike SDL function strings, the return values of user functions can be used in calculations just like a static value, but beware of cases where an operation writes a value back to the parameter—transformations are a good example—which will result in the dynamic user function being replaced by a static value. All that said, with a little care, JavaScript callbacks can be an incredibly powerful tool.

To get around the limitations on side-effects and internal state, remember that every Primitive object has two callback methods, frameBegin and frameEnd. These methods are guaranteed to only be called by CephaloPOV at the beginning and end of a frame, exactly once for each object.

The Animation Cycles

From CephaloPOV's perspective, every user program is an animation. Static scenes are just animations with a single frame. If you're only making static scenes, you don't need to know much about the animation features beyond setting up a scene and triggering its output. Conversely, once you know how to create static scenes, there's not much more you have to know in order to create animations.

One of the major design goals of CephaloPOV was to have more flexible options than POV-Ray's native animation system which, while more than adequate for many animations, can be awkward for others. Consequently, there are two main ways to produce animations in CephaloPOV:

Aside from the greater flexibility of writing procedural code in JavaScript instead of SDL, having both a time counter and a frame counter in automatic mode can make certain kinds of animations and programming styles easier. At the same time, the ability to work within the implicit Newtonian time of the native POV-Ray animation system is preserved.

Animation Parameters

The animation loop is configured through attributes of the global cpov object. All of them are directly writeable by the user program, but some of them should be manipulated with care as noted in the table below.

 ReqNameType(s)Description
RWYcpov.clockTimefloatThis attribute holds the current clock time for the animation. It defaults to 0.0.
RWYcpov.currentFrameintegerThe number of the current frame. In most cases, you should treat this as a read-only value, but there is no reason you can't at least change it to a higher number to skip frames if you do it at the end of the animation loop.
RWYcpov.endFrameintegerThe user program will halt if and when cpov.currentFrame is greater than this number. Defaults to Infinity.
RWYcpov.endTimefloatThe user program will halt if and when cpov.clockTime is greater than this number. Defaults to Infinity.
RWYcpov.settings.frameBeginfunctionThis is a user-supplied callback function which is called at the beginning of the animation loop. It is passed the global cpov object as its sole argument.
RWYcpov.settings.frameEndfunctionThis is a user-supplied callback function which is called at the end of the animation loop. It is passed the global cpov object as its sole argument.
RWYcpov.settings.outputBasestringThe generated .pov and .ini filenames will be based on this template, which defaults to cpov0000. The first sequence of zeroes in the template string will be replaced with the frame number, left-padded with to the same number of digits as the zero sequence.
RWYcpov.settings.snapshotModebooleanIf true, puts CephaloPOV in snapshot mode.
RWYcpov.snapshotsarrayThis is an array containing the output SDL strings which will be written to the .pov file at the end of the frame loop. Normally read-only, but if you know what you're doing, feel free to push() additional content to it.
RWYcpov.startFrameintegerThe user program will run but not produce any output until cpov.currentFrame is greater than or equal to this number. Defaults to 0.
RWYcpov.startTimefloatThe user program will run but not produce any output until cpov.clockTime is greater than or equal to this number. Defaults to 0.
RWYcpov.tickValfloatContains the value added to cpov.clockTime after each iteration of the animation loop. Defaults to 1.0.

Snapshot Mode

Snapshot mode is arguably the easier of the two animation modes to get started with, especially if the animation is simple or you want to construct your own animation loop to suit your needs. Just set cpov.settings.snapshotMode to true, which disables the built-in loop.

cpov.settings.snapshotMode = true;

All you need to do after that is create your objects and call their snapshot methods. If you move them afterwards, you can call snapshot again to "plot" them in their new positions. And once you've created a snapshot of every object you want in the frame, call cpov.outputFrame to generate the .pov/.ini files and clear the snapshot buffer.

Two things are important to remember in snapshot mode. First, your light sources and cameras are objects themselves, so you have to remember to add their snapshots to the buffer in each frame. Second, objects don't magically cease to exist if you only use them once. This may not matter much in short, simple animations, but if you are creating a lot of single-use objects, you'll want to call their destroy methods to avoid filling up memory.

The script that generates the illustrations for this documentation uses snapshot mode. Here's a somewhat simplified version of what it does. (See /docs/illus.js if you want to dig into the full, somewhat hairy details.) First, it just does the usual setup and housekeeping, the only germane part of which is the first line that activates snapshot mode:

cpov.settings.snapshotMode = true; // Don't forget this part cpov.imageOptions.height = 320; cpov.imageOptions.width = 320; cpov.imageOptions.outputFileType = "N"; cpov.imageOptions.createIni = true; cpov.imageOptions.outputAlpha = true; cpov.imageOptions.antialias = true; cpov.imageOptions.antialiasDepth = 9; cpov.globalSettings.ambientLight = [0.25, 0.25, 0.25];

Then it creates the generic texture string that all of the object examples reuse, and it calls an undocumented internal function to produce the stage objects, which come as an array with two members, the stage and lights, and the camera. We go ahead and push those right into the snapshot buffer.

var texture = "texture { pigment { color <1, 1, 0> }}"; var stage = cpov.testStage("corner", 6); stage[0].snapshot(); stage[1].snapshot();

Because this isn't actually an animation, the script sets cpov.settings.outputBase at the beginning of each "frame" to make it easier to find the files. (I'm mentioning this to point out that snapshot mode is also a convenient way to crank out a bunch of static images.)

cpov.settings.outputBase = "./docs/src/box_basic";

Now we can get down to business and create our example box:

var obj = new Box({ corner1: [2,2,2], corner2: [-2, -2, -2] }); obj.snapshot();

And that's it as far as objects go. We just need to output the frame and clean up after ourselves:

cpov.outputFrame(); // This outputs box_basic.pov and box_basic.ini obj.destroy();

Naturally, if you're only doing a single frame or a short animation with relatively few objects, you don't have to bother with calling destroy, but it's a good habit to get into before you start working on more ambitious projects.

Automatic Mode

Automatic mode is not actually any harder to use than snapshot mode. In fact, it's a lot easier because it automates a lot of the stuff you'd otherwise have to do manually, but it does require you to understand the CephaloPOV animation loop, at least if you want to avoid tying yourself into knots. Let's just get that out of the way first:

  1. The global cpov.settings.frameBegin callback is called.
  2. Each object's individual frameBegin callback is called.
  3. All active objects are written to file by cpov.outputFrame.
  4. Each object's individual frameEnd callback is called.
  5. The global cpov.settings.frameEnd callback is called.
  6. The cpov.clockTime is incremented by cpov.tickVal and cpov.currentFrame is incremented.

This loop starts when your program calls cpov.runAnimation and continues until either your program calls cpov.endAnimation, cpov.clockTime exceeds cpov.endTime, or cpov.currentFrame exceeds cpov.endFrame. Besides setting up the initial scene, all you have to do is write the necessary beginFrame and endFrame callbacks.

Callbacks

As far as the callbacks are concerned, how you want to structure things is up to you. If you want, you can stuff all of your logic into cpov.beginFrame and/or cpov.endFrame. You can also leave them set to null and pack everything into the beginFrame and endFrame methods of individual objects. You can also use both. CephaloPOV is not opinionated about your code.

All of the callbacks are the same. Each one is called with a single argument, the global cpov object, which it can then interrogate to determine the current clock value and frame number, as well as use cpov.serialMap or cpov.idMap to find other objects. You can feel free to attach additional data and function members to cpov as well.

Using the Clock and the Frame Count

The animation clock, cpov.clockTime, is a continuous floating-point value that is incremented by cpov.tickVal at the end of each frame and measures time inside the animation. The current frame number, cpov.currentFrame, is a discrete integer value that increases by one at the end of each frame, and which effectively measures the number of times that the simulated world of the animation has been sampled.

You can just use one or the other if your needs are simple enough, but the combination of the two is powerful enough to make it worth understanding their relationship. [TODO]

The cpov Object

From the POV of user programs (see what I did there?), CephaloPOV appears as the global object cpov, so named because it would be a pain to have to type CephaloPOV all the time. Trust me, I know. The innards of cpov are actually pretty short and simple because its main job is to keep track of various settings and just run the user program. Most of the gnarly code lives elsewhere. It does have a few oft-used public methods which will be described after the parameter objects. For a complete list, see the developer documentation.

POV-Ray has two sets of global parameters which remain separate here. The first, represented in CephaloPOV by the cpov.imageOptions object, corresponds to POV-Ray's command line switches and the contents of .ini files. The second is the global_settings block in .pov scene files, which is represented by cpov.globalSettings.

In addition to these, there is a third object, cpov.settings, that contains parameters specific to CephaloPOV to avoid confusion with the POV-Ray specific settings in the other two objects.

cpov.settings

The cpov.settings objects represents the global parameters controlling the operation of CephaloPOV. Some can be set indirectly by command line switches or the config files. All of them are directly accessible to user programs.

Attributes
 ReqNameType(s)Description
RWNdebugintegerDetermines the debugging mode. The legal values are
CodeMeaning
0Debugging mode is turned off.
1Debugging mode is turned on.
2Debugging mode is turned on and fatal errors are ignored. This is mainly useful if you are modifying CephaloPOV itself.
RWNframeBeginfunctionThis callback function is called at the beginning of each frame.
RWNframeEndfunctionThis callback function is called at the end of each frame.
RWNinfilestringThis is the name of the user program file.
RWNoutputBasestringProvides the template for generated filenames. The first substring of zeroes will be replaced with the frame number zero-padded to the same number of digits, and .ini and .pov will be appended to form the filename. The default is "cpov0000".
RWNpreamblestringIf non-null, this specifies a string—presumably SDL—to prepend to all output .pov files. This can also be specified by passing a filename to the -p or --preamble command line switches.
RWNquietModebooleanIf true, console output will be suppressed. Can be set with the -q or --quietMode command line switches.
RWNsdlIncludesbooleanSpecifies an array of one or more SDL include files. These will generate #include statements in the generated .pov files in the order given after the contents of cpov.settings.preamble.
RWNsnapshotModebooleanIf true, snapshot mode will be used for animations.
RWNverbosityintegerSets the verbosity of console output. The default value, 1, permits output of fatal errors and warnings, 2 enables information messages, 3 enables debugging messages. Quiet mode is the same as a verbosity of 0. This value is incremented by the -v command line switch.
Methods
Settings(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers. User programs will rarely have to call the Settings constructor directly as cpov.settings is already initialized.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

cpov.settings.quietMode = false; cpov.settings.snapshotMode = true; // is the same as... cpov.settings.xset({quietMode: false, snapshotMode: true});

cpov.imageOptions

The cpov.imageOptions object represents the global parameters that are set either by POV-Ray command line switches or by .ini files. CephaloPOV itself never uses the command line switches, but they are output in a comment at the beginning of the generated .ini files for the curious. It should be noted that not all of the values that can be set in a .ini file have corresponding command line switches.

By default, CephaloPOV initializes cpov.imageOptions with an ImageOptions object at the beginning of a job. You can create additional ImageOptions objects, but only the one assigned to cpov.imageOptions when cpov.outputFrame() is called is actually used.

All of the parameters are optional except for height and width.

Attributes
 ReqNameType(s)Description
RWYheightintegerHeight of output image in pixels.
RWYwidthintegerWidth of output image in pixels.
RWNallConsolebooleanIf true, POV-Ray debug messages, fatal errors, rendering info, statistics, and warnings are sent to the console.
RWNallFileboolean
string
If true, POV-Ray debug messages, fatal errors, rendering info, statistics, and warnings are written to ALLTEXT.OUT. Alternatively, a custom filename may be specified here.
RWNantialiasbooleanIf true, enables antialiasing.
RWNantialiasDepthintegerSpecifies the number of rows and columns within each pixel to be super-sampled. Values in the range 1-9 are permitted, and the default is 3.
RWNantialiasGammafloatSets the gamma to be used in antialiasing.
RWNantialiasThresholdfloatDefines the amount by which a pixel must differ from its neighbors to trigger supersampling. The default is 0.3.
RWNappendFilebooleanIf true, output from the various runtime log files will be appended to existing files. If false, runtime log files will be overwritten.
RWNbitsPerColorintegerSpecifies the number of bits per color channel in the image file. This only affects PNG and PNM output, which allow 5-16 bits per channel.
RWNboundingbooleanIf true (the default), turns automatic bounding control on.
RWNboundingMethodintegerIf set to 1 (the default), the POV-Ray 3.0+ automatic bounding system is used. If set to 2, the new (and very much beta) Binary Space Partitioning method is used.
RWNboundingThresholdintegerSets the minimum number of objects that must be in a scene before automatic bounding control is used. Defaults to 25.
RWNbspBaseAccessCostfloatParameter for the beta Binary Space Partioning System. See this article for details.
RWNbspChildAccessCostfloatParameter for the beta Binary Space Partioning System. See this article for details.
RWNbspIsectCostfloatParameter for the beta Binary Space Partioning System. See this article for details.
RWNbspMaxDepthfloatParameter for the beta Binary Space Partioning System. See this article for details.
RWNbspMissChancefloatParameter for the beta Binary Space Partioning System. See this article for details.
RWNdebugConsolebooleanIf true, POV-Ray debug messages are sent to the console.
RWNdebugFileboolean
string
If true, POV-Ray debug messages are written to DEBUG.OUT. Alternatively, a custom filename may be specified here.
RWNdisplaybooleanIf true, the image in progress will be displayed during rendering.
RWNdisplayGammafloat
string
A float defining the gamma to be used by the display during rendering or the string "sRGB" (roughly 2.2).
RWNditherbooleanIf true (the default is false), output dithering is used.
RWNditherMethodstringSets the dithering algorithm if dithering is turned on. The supported values are:
CodeMeaning
B2Bayer pattern 2x2
B3Bayer pattern 3x3
B4Bayer pattern 4x4
D1Simple error diffusion 1D
D2Simple error diffusion 2D
FSFloyd-Steinberg error diffusion
RWNendColumninteger
float
Forces the end of output at the specified column if an integer is supplied or a fraction of screen width if a float in the unit interval (0.n) is supplied.
RWNendRowinteger
float
Forces the end of output at the specified row if an integer is supplied or a fraction of screen height if a float in the unit interval (0.n) is supplied.
RWNexePathstringThis should contain the full path to the POV-Ray executable if it is not in the system path.
RWNfatalConsolebooleanIf true, POV-Ray fatal error messages are sent to the console.
RWNfatalErrorCommandstringShell command to execute when POV-Ray encounters a fatal error.
RWNfatalErrorReturnstringSpecifies the action to take when a fatal error occurs during the exectuion of the fatalErrorCommand. Action codes may be prefixed with "-" or "! to negate the action. The legal codes are
CodeMeaning
Aall steps skipped
Fgenerate a fatal error in POV-Ray
Iignore code
Qquit POV-Ray immediately
Sskip one step
Ugenerate a user abort in POV-Ray
RWNfatalFileboolean
string
If true, POV-Ray fatal error messages are written to FATAL.OUT. Alternatively, a custom filename may be specified here.
RWNfileGammafloat
string
Sets the display target gamma for the output file. This may be given as either a float or the string "sRGB" (approx. 2.2).
RWNhighReproducibilitybooleanIf true, enables the experimental high reproducibility mode, which attempts to impose determinism on calculations in SMP environments. Currently only works with radiosity.
RWNincludeHeadersstringAn array containing the names of SDL include files to be referenced in the SDL output.
RWNinputFileNamestringExplicitly sets an input .pov file name.
RWNjitterbooleanIf true, enables random jittering of antialiasing super-samples to minimize artifacts. This should only be used for static scenes, not animation.
RWNjitterAmountfloatDefines the amount of jitter. The default is 1.0, above which super-samples may stray outside of their pixels.
RWNlibraryPathArrayAn array of one or more paths to search for include files.
RWNmaxImageBufferintegerSpecifies the number of megabytes of memory to reserve as an output buffer for images. The default is 128.
RWNoutputAlphabooleanEnables or disables the alpha channel in output files. This only has an effect when the output file type supports alpha, i.e., PNG or Targa.
RWNoutputFileNamestringBy default, the output file name is derived from the .pov scene file name. This option allows it to be set manually. If a directory name is given here instead of a file name, the default name is used and the file is written to the specified directory.
RWNoutputFileTypestringSets the format of the output file. These are all single-character codes as specified below:
CodeMeaning
BBMP
CTGA, RLE compression
EOpenEXR HDR
HRadiance HDR
JJPEG
NPNG
PPPM
SSystem default
TTGA, uncompressed
RWNoutputToFilebooleanIf true (the default), POV-Ray will produce an output image file. If false, no file is produced, which is often desirable when doing test renders.
RWNpalettecharA single character which selects a hardware-dependent palette for display during rendering.
RWNpauseWhenDonebooleanIf true, POV-Ray will wait for a keypress at the end of rendering before clearing the display.
RWNpostSceneCommandstringShell command to execute after rendering a scene. Since CephaloPOV replaces POV-Ray's native animation system, this happens after every frame in an animation.
RWNpostSceneReturnstringSpecifies the action to take when the postSceneAction fails. See fatalExecutionReturn for a list of legal values.
RWNpreSceneCommandstringShell command to execute before rendering a scene. Since CephaloPOV replaces POV-Ray's native animation system, this happens before every frame in an animation.
RWNpreSceneReturnstringSpecifies the action to take when the preSceneAction fails. See fatalExecutionReturn for a list of legal values.
RWNpreviewEndSizeintegerSets the final block size in pixels for mosaic rendering. This must be an integer that is both a power of two and greater than zero.
RWNpreviewStartSizeintegerSets the initial block size in pixels for mosaic rendering. This must be an integer that is both a power of two and greater than zero.
RWNqualityintegerDetermines rendering quality in the range (0 - 11), with higher values being better. The supported levels, with duplication to allow for future changes, are
CodeMeaning
0Just show quick colors. Use full ambient lighting only. Quick colors are used only at 5 or below.
1Just show quick colors. Use full ambient lighting only. Quick colors are used only at 5 or below.
10Compute media, radiosity and subsurface light transport.
11Compute media, radiosity and subsurface light transport.
2Show specified diffuse and ambient light.
3Show specified diffuse and ambient light.
4Render shadows, but no extended lights.
5Render shadows, including extended lights.
6Compute texture patterns, compute photons.
7Compute texture patterns, compute photons.
8Compute reflected, refracted, and transmitted rays.
9Compute media, radiosity and subsurface light transport.
RWNradFileNamestringIf specified, manually sets the name of the radiosity cache file.
RWNradFromFilestringIf true, loads sample data from an existing radiosity cache file.
RWNradToFilestringIf true, saves sample data to a radiosity cache file for reuse.
RWNradVainPretracebooleanIf true (the default), an extra radiosity trace will be taken to improve the quality of the preview. If not needed, this can be turned off to improve rendering speed.
RWNremoveBoundsbooleanIf true (the default), manual bounds will be removed if automatic bounding control is turned on.
RWNrenderBlockSizeintegerSpecifies the size of blocks of pixels to be rendered. Must be 4 or greater.
RWNrenderBlockStepintegerSets the step size for walking through the blocks numbered by renderPattern
RWNrenderConsolebooleanIf true, POV-Ray rendering information is sent to the console.
RWNrenderFileboolean
string
If true, POV-Ray rendering information is written to RENDER.OUT. Alternatively, a custom filename may be specified here.
RWNrenderPatternintegerDetermines the order in which render blocks will be rendered. See the POV-Ray documentation for details.
RWNsamplingMethodintegerSets the antialiasing sampling method. A value of 1, the default, enables non-recursive sampling, while 2 enables adaptive, recursive sampling.
RWNsplitUnionsbooleanIf true, manually bound Union objects will be rebound by the automatic bounding system. The default is false.
RWNstartColumninteger
float
Forces the start of output at the specified column if an integer is supplied or a fraction of screen width if a float in the unit interval (0.n) is supplied.
RWNstartRowinteger
float
Forces the end of output at the specified row if an integer is supplied or a fraction of screen height if a float in the unit interval (0.n) is supplied.
RWNstatisticConsolebooleanIf true, POV-Ray statistics are sent to the console.
RWNstatisticFileboolean
string
If true, POV-Ray statistics are written to STATS.OUT. Alternatively, a custom filename may be specified here.
RWNtestAbortbooleanIf true, POV-Ray will poll the keyboard for Ctrl-C to halt the program. If false, Ctrl-C is ignored.
RWNtestAbortCountintegerIf testAbort is true, testAbortCount specifies the number of pixels rendered between tests for Ctrl-C.
RWNuserAbortCommandstringShell command to execute when the user aborts rendering.
RWNuserAbortReturnstringSpecifies the action to take when the userAbortAction fails. See fatalExecutionReturn for a list of legal values.
RWNverbosebooleanIf true, POV-Ray will output additional information about each render. Not to be confused with CephaloPOV's -v switch, which only increses the verbosity of its own output.
RWNvideoModecharA single character/digit which defines the hardware-dependent video mode.
RWNwarningConsolebooleanIf true, POV-Ray warning messages are sent to the console.
RWNwarningFileboolean
string
If true, POV-Ray warning messages are written to WARNING.OUT. Alternatively, a custom filename may be specified here.
RWNwarningLevelintegerSpecifies POV-Ray's warning level. The legal values are:
CodeMeaning
0Turn off all warnings.
10Turn on all warnings (default).
5Turn off language version warnings.
RWNworkThreadsintegerSets the number of processor threads in a multicore environment. Defaults to the detected number of cores or 4 if detection is not possible, but may be set as high as 512.
Methods
ImageOptions(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers. User programs will rarely have to call the ImageOptions constructor directly as cpov.imageOptions is already initialized.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

cpov.imageOptions.verbose = true; cpov.imageOptions.quality = 9; // is the same as... cpov.imageOptions.xset({verbose: true, quality: 9});

cpov.globalSettings

The cpov.globalSettings class defines the behavior of light in the image along with a few odds and ends like the character set used for input files. At startup, cpov.globalSettings is initialized with a pristine instance of the GlobalSettings class. None of its parameters are mandatory except for assumedGamma, which is initialized to a default value of 1.0.

Attributes
 ReqNameType(s)Description
RWNadcBailoutfloatDefines the Adaptive Depth Control bailout value, which determines when to stop tracing further reflections once they cease to contribute significantly to the color of the current pixel. This defaults to 0.0039 and should not require changing. If it is set to zero, only maxTraceLevel will interrupt the tracing of reflections.
RWNambientLightColorSpecifies the color of the ambient light, i.e., the illumination that falls on every object from all directions in the absence of any explicit LightSource.
RWNassumedGammafloatDefines the working gamma space for the render.
RWNcharsetstringSpecifies which character set will be used in interpreting the contents of text strings. The supported values are "ascii", "sys", and "utf8". The default is ascii.
RWNiridWavelengthColorSpecifies a color to use in iridescence calculations. The default, [0.70, 0.52, 0.48] will rarely if ever need to be changed, but it is available for experimentation.
RWNmaxIntersectionsintegerSets the size of POV-Ray's internal "I-Stacks" for tracking ray/object intersections. The default value for maxIntersections is 64, but if a rendering produces an error message about an I-Stack overflow, you will have to increase this value until the error message disappears.
RWNmaxTraceLevelintegerSets an upper limit on the number of reflections that a ray can undergo before calculations are stopped and the pixel returns as black. Legal values are in the range 1-256. Increase the value only as needed to fix black spots in reflections as higher values require more memory and time to calculate.
RWNmmPerUnitfloatSets the number of millimeters per unit of space in the POV-Ray coordinate system, which affects the behavior of subsurface transport. The default is 10, i.e., 1 cm per unit.
RWNnoiseGeneratorintegerSpecifies which noise generator POV-Ray will use. The default is 2. The legal values are
CodeMeaning
1The original noise generator from POV-Ray 3.1 and earlier
2An improved noise generator with fewer artifacts
3Perlin noise
RWNnumberOfWavesintegerSpecifies the number of waves used by the waves and ripples texture patterns. The default is 10.
RWNphotonbooleanIf true, photons are enabled and the photon* parameters are emitted in output.
RWNphotonAdcBailoutfloatSpecifies an Adaptive Depth Control for photons. If not specified, the regular adcBailout will be used.
RWNphotonAutostopfloatThis is a float in the unit interval (0.0 - 1.0) that determines how much of an object's bounding volume must be tested before aborting. It defaults to 0, but objects with holes often require a higher value.
RWNphotonCountintegerDetermines the number of photons to use. Cannot be used at the same time as photonSpacing
RWNphotonExpandThresholdsArrayAn array of a float in the unit interval (0.0 - 1.0) and an integer which define how much the adaptive search radius can be increased before reverting to photonRadius and the minimum number of photons to gather, respectively. The default is [0.2, 40].
RWNphotonGatherArrayThis is an array of two integers which specify the minimum and maximum number of photons to gather at each point. The default is [20, 100].
RWNphotonJitterfloatSpecifies the amount of jitter to use in the pre-processing step. The default is 0.4 and rarely needs to be changed.
RWNphotonLoadFilestringSpecifies a photon map to load instead of performing the calculations.
RWNphotonMaxTraceLevelintegerSets an upper limit on the number of reflections that a photon can undergo before calculations are stopped. Legal values are in the range 1-256. If unspecified, the global maxTraceLevel is used.
RWNphotonMediaArrayIf specified, media photons are enabled. This is an array of an integer and a float. The integer specifies the maximum number of photons to deposit over an interval, and the float specifies the difference in media spacing relative to surface spacing.
RWNphotonRadiusArrayThis is an array of four floats that specify the gather radius, its multiplier, the media gather radius, and its multiplier.
RWNphotonSaveFilestringSaves the calculated photon map to this file for reuse.
RWNphotonSpacingfloatSpecifies the average distance between photons on surfaces. Cannot be used at the same time as photonCount.
RWNradAdcBailoutfloatSpecifies an Adaptive Depth Control for radiosity rays. The default is 0.01.
RWNradAlwaysSamplebooleanIf true, new samples will be gathered during the final radiosity pass. This is slower and often produces lower-quality results, so the default is false, but there are some cases where turning it on can correct blotchy imperfections.
RWNradBrightnessfloatSpecifies the amount by which the brightness of objects should be adjusted before being returned to the rest of the system. The default value is 1.0 and should almost never be changed; individual object properties should be adjusted instead.
RWNradCountArrayThis is an array which specifies the number of radiosity rays emitted when a new radiosity value is needed. The default is 35. The second, optional element sets the number of directions to choose rays from.
RWNradErrorBoundfloatSpecifies the tolerated error and defaults to 1.8. Lower values are more accurate but require higher radCount values to avoid artifacts and dramatically increase rendering times.
RWNradGrayThresholdfloatThis is a float in the unit interval (0.0 - 1.0) that counteracts color bleed by desaturating reflected light. At 0.0 (the default), it has no effect, while at the other extreme, 1.0, reflected light is greyscale only.
RWNradiositybooleanIf true, radiosity is enabled and the rad* parameters are emitted in output.
RWNradLowErrorFactorfloatThe radErrorBound is multiplied by radLowErrorFactor during preliminary passes to reduce the blotchy artifacts that would otherwise occur. The default is 0.5.
RWNradMaximumReusefloatSets an upper bound on the reuse of samples. See the POV-Ray documentation for more details.
RWNradMaxSamplefloatDefines an upper limit on the brightness of radiosity samples, which can correct for some brightness artifacts at the expense of realism. Setting radMaxSample to a negative value (the default) will disable it.
RWNradMinimumReusefloatSets a lower bound on the reuse of samples. See the POV-Ray documentation for more details.
RWNradNearestCountintegerSpecifies minimum number of old radiosity values blended together to create a new interpolated value. Defaults to 5 with an upper limit of 20.
RWNradNormalbooleanIf true, radiosity will be affected by normals.
RWNradPretraceEndfloatSpecifies the size of mosaic blocks at the end of the pretrace phase as a fraction of image size. This is float in the unit interval (0.0 - 1.0).
RWNradPretraceStartfloatSpecifies the size of mosaic blocks at the start of the pretrace phase as a fraction of image size. This is float in the unit interval (0.0 - 1.0).
RWNradRecursionLimitintegerDetermines how many recursion levels are used to calculate the diffuse inter-reflection. The legal range is 1 - 20, but values above 3 are rarely useful.
RWNradSubsurfacebooleanIf true, radiosity calculations will take subsurface light transport into account. This will increase realism where translucent objects are concerned at the expense of increased rendering time.
RWNsubRadiositybooleanIf true, subsurface effects will be applied to incoming radiosity illumination.
RWNsubSamplesArrayThis is an array of two integers which set the number of samples to use for diffuse scattering and single-scattering approximation. The default for both is 50.
RWNsubsurfacebooleanIf true, subsurface light transport is enabled and the sub* parameters are emitted in output.
Methods
GlobalSettings(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers. User programs will rarely have to call the GlobalSettings constructor directly as cpov.globalSettings is already initialized.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

cpov.globalSettings.numberOfWaves = 3; cpov.globalSettings.charset = "utf8"; // is the same as... cpov.globalSettings.xset({numberOfWaves: 3, charset: "utf8"});

cpov Methods

This section only lists public methods commonly used in user programs. For the complete list, see the developer documentation.

cpov.deg2rad(deg)

Converts the value of deg from degrees to radians and returns the result.

cpov.endAnimation()

When called by the user program, this method terminates the animation loop. If a frame is in progress when it is called, it will not be output, so it is normally called after file output.

cpov.error(level, message, location = "CEPHALOPOV", obj = null)

Outputs an error message using pretty colors if supported by the terminal. The level argument may be one of "fatal", "warn", "info", or "debug". If level is "fatal", the program terminates immediately unless cpov.settings.debug is greater than 1. (This is useful for debugging when working on CephaloPOV itself.) All other error levels simply emit an error message. This will appear on the terminal for "warn", "info", and "debug" at cpov.verbosity levels of 1, 2, and 3, respectively. In all cases, the error will also be written to cpov.settings.debugLog if initialized.

The error message is prefixed with the location where the error occurred, usually a class and method name, and the object serial and id, if any, are appended to the end of the line.

cpov.outputFrame()

The cpov.outputFrame method exists for user programs to call whenever they have finished setting up a scene. It takes no arguments, its behavior being determined mostly by cpov.imageOptions and cpov.globalSettings. That behavior is already described in great detail in The Animation Cycles and will not be repeated here.

There is no return value. If any termination conditions are met, CephaloPOV will terminate with an exit code of 0.

cpov.requireOptLib(alias)

CephaloPOV includes a number of optional libraries that are not automatically loaded at runtime. Each is identified by a mnemonic alias passed to cpov.requireOptLib, which in turn loads the library and returns it to the caller. Many of these are ports of POV-Ray include files to JavaScript identified by their original filename, e.g., colors.inc.

cpov.runAnimation()

This is the main animation loop which repeats, calling cpov.outputFrame() repeatedly until one of its termination conditions are met or the user program calls cpov.endAnimation.

Vectors, Colors, and Matrices

Most of the geometry in POV-Ray is defined in terms of vectors, i.e., arrays of floats whose interpretation depends on context. For the sake of better type checking, CephaloPOV implements vectors as distinct classes even though some of them, like VectorUV and VectorXY, are identical save for their attribute names.

Because initializing vector objects involves more typing than POV-Ray's admirably concise generic notation, all of CephaloPOV's vector types and other object methods that accept vectors will take JavaScript arrays as initializers in addition to the generic JavaScript objects that all CephaloPOV class constructors accept.

var vec = new VectorXYZ(); // The long way vec.x = 2; vec.y = -1; vec.z = 5.2; var vec = new VectorXYZ({ x: 2, y: -1, z: 5.2 }); // The shorter generic way var vec = new VectorXYZ([2, -1, 5.2]); // The shortest way // A vector can also copy the values of another vector: var vec1 = new VectorXYZ([3, 4, 5]); var vec2 = new VectorXYZ(vec1); // Since you rarely ever need a bare vector, you can also assign arrays // to vector attributes in other objects: var box = new Box(); box.corner1 = [ 0, 0, 0 ]; box.corner2 = [ 1, 1, 1 ];

Like most CephaloPOV objects, all of the vector classes have a toSDL() method which returns the vector in the form of an SDL string.

VectorUV

The VectorUV class is used to define 2D coordinates on the UV plane for texture mapping. Aside from having coordinates named u and v, it is otherwise identical to VectorXY.

Attributes
 ReqNameType(s)Description
RWYufloatThe U coordinate of the vector.
RWYvfloatThe V coordinate of the vector.
Methods
asArray(mode = "normal")

Depending on the value of mode, returns the internal coordinates as a two-element array or, in one case, a null indicating an error condition. The legal values of mode and their results are:

ValueResults
"normal" This is the default. Returns a copy of this.raw in which all JavaScript functions have been replaced by their return values.
"literal" Returns an exact copy of the internal representation.
"calc" As with "normal", except that the presence of an SDL function will return null instead of the expected array. CephaloPOV uses this internally to determine whether a VectorUV can be used in numeric computations.
"sdl" As with "normal", except that SDL functions are included, minus the leading ampersand. CephaloPOV uses this internally to generate SDL output.
VectorUV(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers, an array of two floats, or another VectorUV object. The following are all equivalent:

var vec1 = new VectorUV({ u: 1, v: 3 }); var vec2 = new VectorUV([1, 3]); var vec3 = new VectorUV(vec1);
toSDL(stops);

Returns the SDL representation of the vector as a string, indented by the optional number of tab stops. If the mandatory attributes are not specified, a fatal error message is emitted and CephaloPOV halts.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

vec.u = 4; vec.v = 3.2;; // is the same as... vec.xset({u: 4, v: 3.2});

VectorXY

The VectorXY class is used to define 2D coordinates. It is mostly used to define splines and the outlines of objects which are essentially sweeps, like the Prism. (For prisms, the points defined are actually on the XZ plane and the shape is swept along the Y axis, but coming up with a separate VectorXZ seems excessively pedantic.

Attributes
 ReqNameType(s)Description
RWYxfloatThe X coordinate of the vector.
RWYyfloatThe Y coordinate of the vector.
Methods
VectorXY(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers, an array of two floats, or another VectorXY object. The following are all equivalent:

var vec1 = new VectorXY({ x: 1, y: 3 }); var vec2 = new VectorXY([1, 3]); var vec3 = new VectorXY(vec1);
asArray(mode = "normal")

Depending on the value of mode, returns the internal coordinates as a two-element array or, in one case, a null indicating an error condition. The legal values of mode and their results are:

ValueResults
"normal" This is the default. Returns a copy of this.raw in which all JavaScript functions have been replaced by their return values.
"literal" Returns an exact copy of the internal representation.
"calc" As with "normal", except that the presence of an SDL function will return null instead of the expected array. CephaloPOV uses this internally to determine whether a VectorXY can be used in numeric computations.
"sdl" As with "normal", except that SDL functions are included, minus the leading ampersand. CephaloPOV uses this internally to generate SDL output.
toSDL(stops);

Returns the SDL representation of the vector as a string, indented by the optional number of tab stops. If the mandatory attributes are not specified, a fatal error message is emitted and CephaloPOV halts.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

vec.x = 4; vec.y = 3.2;; // is the same as... vec.xset({x: 4, y: 3.2});

VectorXYZ

Probably the most commonly used vector type for most users, the VectorXYZ class defines points in three-dimensional space.

Attributes
 ReqNameType(s)Description
RWYxfloatThe X coordinate of the vector.
RWYyfloatThe Y coordinate of the vector.
RWYzfloatThe Z coordinate of the vector.
Methods
VectorXYZ(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers, an array of three floats, or another VectorXYZ object. The following are all equivalent:

var vec1 = new VectorXYZ({ x: 1, y: 3, z: 4 }); var vec2 = new VectorXYZ([1, 3, 4]); var vec3 = new VectorXYZ(vec1);

Depending on the value of mode, returns the internal coordinates as a three-element array or, in one case, a null indicating an error condition. The legal values of mode and their results are:

ValueResults
"normal" This is the default. Returns a copy of this.raw in which all JavaScript functions have been replaced by their return values.
"literal" Returns an exact copy of the internal representation.
"calc" As with "normal", except that the presence of an SDL function will return null instead of the expected array. CephaloPOV uses this internally to determine whether a VectorXYZ can be used in numeric computations.
"sdl" As with "normal", except that SDL functions are included, minus the leading ampersand. CephaloPOV uses this internally to generate SDL output.
toSDL(stops);

Returns the SDL representation of the vector as a string, indented by the optional number of tab stops. If the mandatory attributes are not specified, a fatal error message is emitted and CephaloPOV halts.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

vec.x = 4; vec.y = 3.2;; // is the same as... vec.xset({x: 4, y: 3.2});

VectorXYZW

The VectorXYZW class defines points in four-dimensional space, and as such, it is not often used. One use case is the four-dimensional JuliaFractal. In the Polynomial type, it is used as a convenient (and somewhat hackish) way of grouping sets of four floats that are not actually coordinates.

Attributes
 ReqNameType(s)Description
RWYxfloatThe X coordinate of the vector.
RWYyfloatThe Y coordinate of the vector.
RWYzfloatThe Z coordinate of the vector.
RWYwfloatThe W coordinate of the vector.
Methods
VectorXYZW(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers, an array of four floats, or another VectorXYZW object. The following are all equivalent:

var vec1 = new VectorXYZW({ x: 1, y: 3, z: 4, w: -1 }); var vec2 = new VectorXYZW([1, 3, 4, -1]); var vec3 = new VectorXYZW(vec1);

Depending on the value of mode, returns the internal coordinates as a four-element array or, in one case, a null indicating an error condition. The legal values of mode and their results are:

ValueResults
"normal" This is the default. Returns a copy of this.raw in which all JavaScript functions have been replaced by their return values.
"literal" Returns an exact copy of the internal representation.
"calc" As with "normal", except that the presence of an SDL function will return null instead of the expected array. CephaloPOV uses this internally to determine whether a VectorXYZW can be used in numeric computations.
"sdl" As with "normal", except that SDL functions are included, minus the leading ampersand. CephaloPOV uses this internally to generate SDL output.
toSDL(stops);

Returns the SDL representation of the vector as a string, indented by the optional number of tab stops. If the mandatory attributes are not specified, a fatal error message is emitted and CephaloPOV halts.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

vec.x = 4; vec.y = 3.2;; // is the same as... vec.xset({x: 4, y: 3.2});

Color

The Color class is used to represent RGB colors. In addition to the usual r, g, and b attributes, it has two optional attributes, f (filter) and t (transmit). There is a final optional boolean attribute, sRGB which, if true, maps the colors to the sRGB color space.

Attributes
 ReqNameType(s)Description
RWYrfloatThe red component of the color, in the unit interval (0.0-1.0).
RWYgfloatThe green component of the color, in the unit interval (0.0-1.0).
RWYbfloatThe blue component of the color, in the unit interval (0.0-1.0).
RWNffloatThe filter component of the color, in the unit interval (0.0-1.0).
RWNtfloatThe transmit component of the color, in the unit interval (0.0-1.0).
RWNsrgbfloatIf true, specifies sRGB gamma values. This will produce an error when POV-Ray parses CephaloPOV's output if cpov.globalSettings.assumedGamma is not set.
Methods
Color(options)

The constructor may be called without arguments, returning an object with its attributes initialized to null. The options argument may also be a plain JavaScript object containing named initializers, an array of three to six values, or another Color object. The following are all equivalent:

var color1 = new Color({ r: 1.0, g: 0.2, b: 0.33, f: 0.2, t: 1.0, srgb: true }); var color2 = new Color([1.0, 0.2, 0.33, 0.2, 1.0, true]); var color3 = new Color(color2);

Note that the f, t, and srgb attributes are optional, so none, any, or all of them can be used, but they must be specified in order when passing a bare array.

toSDL(stops);

Returns the SDL representation of the vector as a string, indented by the optional number of tab stops. If the mandatory attributes are not specified, a fatal error message is emitted and CephaloPOV halts.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

color.r = 0.2; vec.g = 1.0;; // is the same as... vec.xset({r: 0.2, g: 1.0});

Matrix

The Matrix type is the workhorse of transformations and one of the areas where CephaloPOV differs most from the way POV-Ray handles transformations, though this is more a matter of syntax than anything else.

Attributes
 ReqNameType(s)Description
RWYv00floatRow 0, column 0 of the matrix.
RWYv01floatRow 0, column 1 of the matrix.
RWYv02floatRow 0, column 2 of the matrix.
RWYv10floatRow 1, column 0 of the matrix.
RWYv11floatRow 1, column 1 of the matrix.
RWYv12floatRow 1, column 2 of the matrix.
RWYv20floatRow 2, column 0 of the matrix.
RWYv21floatRow 2, column 1 of the matrix.
RWYv22floatRow 2, column 2 of the matrix.
RWYv30floatRow 3, column 0 of the matrix.
RWYv31floatRow 3, column 1 of the matrix.
RWYv32floatRow 3, column 2 of the matrix.
Methods
Matrix(v00, v01, v02, v10, v11, v12, v20, v21, v22, v30, v31, v32);

In its basic form, which few users will often use, the constructor takes twelve floats for each of the values in the matrix, just as it is done in SDL. Like SDL, there are several short convenience forms for the basic transformations:

var scale = new Matrix("scale", 1.5, 2, 1); var translate = new Matrix("translate", 5, 2.2, 0); var rotate = new Matrix("rotate", 45, 15, 0); var scale = new Matrix("scale", 2.2); var translate = new Matrix("translate", 5); var rotate = new Matrix("rotate", 45);

In the first set of the examples above, the name of the transformation is the first argument, followed by three float arguments, one for each of the axes. In the second set, the single float is applied to all three axes. As with POV-Ray, the values for rotations are given in degrees.

The Matrix constructor has a few additional short forms. One lets you specify skews without having to construct the whole matrix by hand. Just pass "skew" as the first argument, and the second argument is an object containing the axis pairs to perform the skew by, like so:

var skew = new Matrix("skew", { xy: 1.5, zy: 0.2 });

The complete set of axis pairs is yx, zx, xy, zy, xz, and yz. You can omit the pairs you don't need.

In another, you can just pass "none" as the sole argument and get a Matrix that does nothing. This is useful if your "base" transformation (see the Primitive type for more details) doesn't require any actual transformations.

asArray(mode = "normal")

Depending on the value of mode, returns the internal matrix representation as a 12-element array or, in one case, a null indicating an error condition. The legal values of mode and their results are:

ValueResults
"normal" This is the default. Returns a copy of this.raw in which all JavaScript functions have been replaced by their return values.
"literal" Returns an exact copy of the internal representation.
"calc" As with "normal", except that the presence of an SDL function will return null instead of the expected array. CephaloPOV uses this internally to determine whether a Matrix can be used in numeric computations.
"sdl" As with "normal", except that SDL functions are included, minus the leading ampersand. CephaloPOV uses this internally to generate SDL output.
copyFrom(that)

Copies the values from that to this Matrix.

isIdentityMatrix()

Returns true if this.raw is the same as the identity matrix with which it was initialized. Note that this only compares literal numeric values. If the members of the array are functions, this method will return false even if the end result is the identity matrix.

rotate(x, y, z)

This is a convenience method for applying a rotation to the current Matrix. Values are in degrees, and if y and z are undefined, the value of x will be used for both of them.

scale(x, y, z)

This is a convenience method for applying a scale transformation to the current Matrix. If y and z are undefined, the value of x will be used for both of them.

skew(pairs)

This is a convenience method for applying skew transformations to the current Matrix. As with the similar convenience form in the constructor, the pairs of axes are passed as members of the pairs object, e.g.

someMatrix.skew({ yx: 1.5 });
translate(x, y, z)

This is a convenience method for applying a translation to the current Matrix. If y and z are undefined, the value of x will be used for both of them.

toSDL(stops);

Returns the SDL representation of the matrix as a string, indented by the optional number of tab stops. Unlike most other toSDL methods, this one always succeeds because the constructor either requires or supplies all of the mandatory values.

xMatrix(that);

Given another Matrix, that, returns a new Matrix that is the product of this × that.

xPoint(point);

Given a VectorXYZ, point, returns a new VectorXYZ which has been transformed by the matrix.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

matrix.v01 = 4; matrix.v02 = 3.2; // is the same as... matrix.xset({v01: 4, v02: 3.2});

Geometric Primitives

Primitive

The Primitive type is the base class for all of the other geometric primitives. Unless you're implementing a new primitive, perhaps for one of the experimental forks of POV-Ray like MegaPOV, you don't need to worry about its internals, but you do need to be familiar with the public attributes and methods it shares with all of its subclasses.

Transformations

Two of those attributes, baseTransform and transform, are important enough to discuss outside of the attributes table, below. In order to support several significant features now and in the future, CephaloPOV distinguishes between an initial transformation that is effectively part of the definition of an object and subsequent transformations applied to it. That initial transformation is the baseTransform, and the subsequent transformations are combined mathematically in the transform attribute.

When a Primitive is output to SDL, the current value of its transform attribute is included in the object definition. The baseTransform is kept internal to CephaloPOV to help with geometric queries and the scene graph system. Most of the time, you won't have to do anything more than set the baseTransform, though it can be useful in user code in snapshot mode, as we will see.

The easiest way and clearest way to establish the baseTransform is simply to assign it:

someBox.baseTransform = new Matrix("rotate", 0, 45, 15);

If you don't set baseTransform explicitly, setting transform will set it at the same time. Naturally, if you are defining an object that doesn't change from frame to frame and its initial parameters are fine without any transformations at all, you don't have to bother with either transform attribute.

Each time thereafter that you set transform, the supplied Matrix is multiplied by the existing transform value. Because of the way matrix multiplication works, this will effectively add the new transformation to the transformations that have already been applied. If you want to start over fresh with the baseTransform value, just call the resetTransform method.

The main purpose of all of this behind-the-scenes plumbing is to provide the necessary basis for higher-level features like the not yet implemented scene graph, and you don't have to worry about it much in your own user programs. One exception to this is if you are using snapshot mode, where multiple output objects can be created using a single primitive object and repeatedly setting transform and then calling baseTransform.

Like most other object attributes in CephaloPOV, transformations can be either the necessary type (in this case Matrix), or a JavaScript function returning a Matrix, or SDL code supplied as a string with the usual "&" prefix. Barring bugs, all three are perfectly fine, but transform is frequently the subject of matrix multiplication at the JavaScript level. How does this work?

A numeric Matrix performs exactly as expected. SDL strings will halt the program with an error. If transform is a JavaScript function returning a Matrix, it will be replaced with its return value and then altered accordingly. The same applies to JavaScript functions as individual matrix elements. This is one of the few places that the difference between the three execution scopes—CephaloPOV, the user program, and POV-Ray—is so important to understand clearly. The power and flexibility of the approach is great, but you can expect a little eye-crossing confusion at first.

Attributes
 ReqNameType(s)Description
RWNactivebooleanIf active == false, it will not be output to the current .pov frame file. Defaults to true.
RWNbaseTransformMatrixThe baseTransform attribute contains the "default" transformation of the object. As new transformations are applied, the original baseTransform remains unchanged, making it easy to revert to the original state by calling the resetTransform method.
RWNboundedByPrimitiveDefines a manual bounding volume for the object.
RWNclippedByPrimitiveSpecifies a solid Primitive that the object is clipped by in a manner similar to CSG intersection.
RWNdeclarebooleanIf true, the object is emitted as an object declaration using id as its identifier.
RWNdoubleIlluminatebooleanIf true, the object is illuminated on its shadow side.
RWNframeBeginfunctionIf defined, this function will be called at the beginning of a frame before output.
RWNframeEndfunctionIf defined, this function will be called at the end of a frame after output.
RWNhollowbooleanIf true, this will make an otherwise solid primitive hollow. Has no effect on objects which are not solid.
RWNidstringAn optional, unique string which serves to identify an object. While you can pull objects out of cpov.idMap using this value, it is output in error messages, making it easier to find the offending object.
RWNinteriorInteriorNOT IMPLEMENTED YET
RWNinversebooleanIf true, the inside and outside of the solid object are swapped. For example, a hollow Sphere would consist of a spherical void in an infinite solid mass. This is mainly useful in CSG objects.
RWNmaterialMaterialNOT IMPLEMENTED YET
RWNnoImagebooleanIf true, the object will be invisible to cameras, but it will still cast shadows and show up in reflections.
RWNnoRadiositybooleanIf true, the object will be invisible to radiosity rays.
RWNnoReflectionbooleanIf true, the object will not be visible in reflections.
RWNnoShadowbooleanIf true, the object will not cast shadows.
RONparentPrimitiveThis is a read-only reference to the parent object of which the current object is a component, e.g., Blob, Mesh, and CSG objects.
RWNphotonsTODOTODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec tellus quis turpis pretium condimentum ut eget neque. Integer pharetra imperdiet elit, eu malesuada tortor.
RWNradiosityTOODTODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec tellus quis turpis pretium condimentum ut eget neque. Integer pharetra imperdiet elit, eu malesuada tortor.
RWNsatellites[Primitive]This is an array of Primitive objects to which the same transformations will be applied as to the parent. Among other things, this makes it possible to attach one or more Cameras to an object.
RWNSDLAppendstringA string supplied here (presumably SDL) will be output after the object. It does not require the usual '&' prefix.
RWNSDLPrependstringA string supplied here (presumably SDL) will be output before the object. It does not require the usual '&' prefix.
RWNserialintegerThis is a unique read-only integer serial number automatically assigned by CephaloPOV upon object creation. It is displayed in error messages, and objects can be looked up using cpov.serialMap.
RWNtexturestringPending implementation of CephaloPOV's texture subsystem, this is a literal SDL string which will be output as-is.
RWNtransformMatrixThis is a Matrix representing the current transformation state of the object, as distinct from baseTransform, which represents its original state. Matrix values assigned to the transform attribute are silently multiplied against its current value.
Methods
resetTransform();

Restores the object's current transform to the value of its baseTransform.

rotate(x, y, z)

This is a convenience method for applying a rotation to the current object. Values are in degrees, and if y and z are undefined, the value of x will be used for both of them.

scale(x, y, z)

This is a convenience method for applying a scale transformation to the current object. If y and z are undefined, the value of x will be used for both of them.

skew(pairs)

This is a convenience method for applying skew transformations to the current object. As with the similar convenience form in the constructor, the pairs of axes are passed as members of the pairs object, e.g.

someObj.skew({ yx: 1.5 });
snapshot();

If cpov.settings.snapshotMode is true, this method sends the output of toSDL to the snapshot output buffer, where it will remain until cpov.outputFrame is called.

toSDL(stops);

Returns the SDL representation of the Primitive as a string, indented by the optional number of tab stops. User programs will seldom if ever call this directly, but it is overridden and called by the toSDL methods in the subclasses. Those subclass methods will emit a fatal error message if any mandatory attributes are not specified, but the Primitive base class has no mandatory attributes, so this call will always succed.

translate(x, y, z)

This is a convenience method for applying a translation to the current object. If y and z are undefined, the value of x will be used for both of them.

xset(valObj)

This is a convenience function which takes an object full of key/value pairs and sets several attributes at the same time, much like the constructor, which avoids having to set them individually. The following are equivalent:

box.corner1 = [-1, -1, -1]; box.corner2 = [1, 1, 1]; // is the same as... box.xset({corner1: [-1, -1, -1], corner2: [1, 1, 1]});

BicubicPatch

The BicubicPatch type is a curved surface defined by a 4 × 4 array of VectorXYZ control points which are interpolated behind the scenes using Bezier splines and converted to a mesh of triangles. The number of triangles used along the u- and v-axes are defined by uSteps and vSteps.

var obj = new BicubicPatch({ type: 0, flatness: 0.01, uSteps: 4, vSteps: 4, points: [ [0, 2, 0], [0, 0, 1], [0, 0, 2], [0, -2, 3], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 0, 3], [3, 2, 0], [3, 0, 1], [3, 0, 2], [3, -2, 3] ] });
Attributes
 ReqNameType(s)Description
RWYpoints[VectorXYZ]The points attribute is an array of 16 VectorXYZ points which define the 4 × 4 array of control points that define the patch.
RWYtypeintegerThis may be either 0 or 1. Type 0 reduces the amount of memory used to store the patch in memory at the cost of slower rendering. Type 1 does the reverse, consuming more memory but reducing the number of calculations required.
RWNflatnessfloatIf flatness is 0 (the default), the patch will be subdivided into only as many triangles as specified by uSteps and vSteps. Increasing it up to a maximum of 1.0 will encourage POV-Ray to automatically subdivide the patch into additional triangles as needed.
RWNuStepsintegerDefines the number of rows of triangles used to create the patch. Most patches can be acceptably rendered using 3 rows.
RWNvStepsintegerDefines the number of columns of triangles used to create the patch. Most patches can be acceptably rendered using 3 columns.
RO csgbooleanIf true, the primitive is a composite CSG container. For a BicubicPatch, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a BicubicPatch, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a BicubicPatch, this is always true.
RO solidbooleanIf true, the shape is solid. For a BicubicPatch, this is always false.

Blob

The Blob type is an isosurface of scalar fields produced by points and lines represented in the components array by Sphere and Cylinder objects. What this means in practice is that each object has a field strength that starts at the center of the object and drops to zero at its radius. The surface of the blob is wherever the overlapping fields have a value equal to the blob's threshold value, which defaults to 1.0. The effect is a smooth surface like drops and strings of honey.

This makes the Blob an excellent tool for building smooth, organic shapes. In the simple example here, a Blob composed of three Sphere objects forms a lumpy diagonal line through the demo stage space.

var obj = new Blob({ components: [ new Sphere({ center: [-1.5, -1.5, -1.5], radius: 2, strength: 4 }), new Sphere({ center: [ 0, 0, 0], radius: 2, strength: 4 }), new Sphere({ center: [ 1.5, 1.5, 1.5], radius: 2, strength: 4 }), ] });
Attributes
 ReqNameType(s)Description
RWYcomponentsArrayThis is an array of Sphere and Cylinders, optionally with their strength attributes set.
RWNhierarchyhierarchyIf false, turn off the internal bounding hierarchy.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RWNthresholdfloatThe threshold determines the field strength that distinguishes between the inside and outside of a Blob, i.e., threshold defines the surface of a Blob.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Blob, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Blob, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Blob, this is always true.
RO solidbooleanIf true, the shape is solid. For a Blob, this is always true.

Box

The Box type is exactly what it sounds like: a rectangular box. It is defined by the coordinates of two diagonally opposite corners, corner1 and corner2. Its sides are orthogonal to the axes, so other orientations will require applying a transformation. The example at right was created by the following code:

var obj = new Box({ corner1: [2, 2, 2], corner2: [-2, -2, -2] });
Attributes
 ReqNameType(s)Description
RWYcorner1VectorXYZThe first of two opposite corners of the cube.
RWYcorner2VectorXYZThe first of two opposite corners of the cube.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Box, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Box, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Box, this is always true.
RO solidbooleanIf true, the shape is solid. For a Box, this is always true.

Camera

Camera objects provide a point of view in the scene. There can be many in a scene, but only one can have its active flag set to true when a frame is output. POV-Ray will happily accept multiple cameras, but it only uses the last one defined in the .pov file. In keeping with CephaloPOV's philosophy of catching errors early so you don't have to puzzle over a broken SDL script, only the first active camera is output and a warning is issued for the others.

Unlike a LightSource, POV-Ray will for some reason not allow cameras to be part of CSG operations, hence Camera.csgOperand is always false. Because it is often extremely useful to attach a camera to an object and doing so manually would involve a lot of extra code for user programs, CephaloPOV's Primitive class includes a satellites attribute that provides an easy workaround. A simple array of other Primitive objects, transformations applied to the parent are applied to each of the satellite objects, keeping them in the same relationship to the parent as when they were defined. Technically, any Primitive can be used as a satellite, but you're probably best off sticking to Union or Merge CSG objects, as they are more robust.

Attributes
 ReqNameType(s)Description
RWYtypestringDefines the type of the camera. The legal values are
CodeMeaning
cylindercylinder
fisheyefisheye
meshCameramesh_camera
omnimaxomnimax
orthographicorthographic
panoramicpanoramic
perspectiveperspective
sphericalspherical
ultraWideAngleultra_wide_angle
RWNanglefloat|[float]When passed as a single float, sets the horizontal viewing angle in degrees. This alters the direction vector, setting it to 0.5 * right / Math.tan(angle/2). For perspective cameras, angle must be less than 180 degrees. For spherical cameras, angle can be passed as an array of two floats, the second element specifies the vertical viewing angle. If not specified, the vertical angle defaults to one-half of the horizontal angle.
RWNaperturefloatWhen specified along with blurSamples, simulated depth-of-field is enabled, and aperture is inversely proportional the depth of the zone of sharpness. It functions similarly to f-stops, but does not map directly to them.
RWNblurSamplesfloat|[float]Specifies the minimum and, optionally, maximum number of samples to be used when aperture is non-zero. Values of 4, 7, 19, and 37 yield square bokeh, and all others produce round bokeh.
RWNbokehColorSpecifies the bokeh color.
RWNconfidencefloatSpecifies the confidence interval that determines when enough samples have been taken when aperture is non-zero, with higher values resulting in greater precision. The default is 0.9.
RWNcylinderTypeintegerIf the cylinder camera type is used, cyliderType must be set with an integer in the range 1-4. These values correspond to
CodeMeaning
1Vertical cylinder, fixed viewpoint. The axis lies along the up vector, and width is determined by right unless overridden by angle.
2Horizontal cylinder, fixed viewpoint. The axis lies along the right vector.
3vertical cylinder, viewpoint moves along the cylinder's axis. The axis lies along the up vector, and width is determined by right unless overridden by angle. The up vector determines the height of the image, and viewing rays are perpendicular to the up vector.
4horizontal cylinder, viewpoint moves along the cylinder's axis. The axis lies along the right vector, and viewing rays are perpendicular to right.
RWNdirectionVectorXYZSets the direction vector of the camera before it is moved by lookAt and any rotations. For some camera types, this controls the horizontal field of view: shorter vectors zoom out and longer vectors zoom in. For most purposes, you will not need to set direction manually, using the easier angle attribute, but see the POV-Ray docs for more details. The default is [0, 0, 1]. Unit-length vectors should be used with ultraWideAngle, panoramic, and cylindrical cameras. The direction vector is ignored by orthographic, fisheye, and omnimax cameras.
RWNfocalPointVectorXYZSpecifies the point at which the image is perfectly focused when aperture is non-zero. This defines a point on a plane parallel to the view and defaults to [0, 0, 0].
RWNlocationVectorXYZSpecifies the location of the camera.
RWNlookAtVectorXYZIf supplied, the camera will be aimed at this point by panning and tilting from the origin in conjunction with the sky vector.
RWNrightVectorXYZAlong with up, the right vector determines how POV-Ray calculates the aspect ratio of the image. By default, it is [1.33, 0, 0]. The cylindrical and orthographic cameras have different behaviors, for which see the POV-Ray docs. It also determines the handedness of the coordinate system.
RWNskyVectorXYZDetermines where "up" is for the camera before lookAt is applied, allowing the camera to be tilted. By default, this is [0, 1, 0].
RWNupVectorXYZAlong with right, the up vector determines how POV-Ray calculates the aspect ratio of the image. By default, it is [0, 1, 0]. The cylindrical and orthographic cameras have different behaviors, for which see the POV-Ray docs.
RWNvariancefloatWhen aperture is non-zero, variance tells POV-Ray the value of the smallest displayable color difference. The default, 0.0078125 (1/128), can produce fairly grainy images. To fix this, try a value around 0.00001.
RWNvertAnglefloatFor the spherical camera, this defines the vertical angle of the viewing area while angle specifies the horizontal angle.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Camera, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Camera, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Camera, this is always true.
RO solidbooleanIf true, the shape is solid. For a Camera, this is always false.
Methods

TODO

Cone

The Cone type is deceptively simple. At a minimum, you must specify a basePoint and a capPoint along with their respective radii. For the result to be a cone, one of the radii must be zero, but non-zero values will produce a frustum, i.e., a truncated cone. You can also remove the endcaps and create a hollow cone by setting open to true. The example at right was created by the following code:

var obj = new Cone({ basePoint: [0, -2, 0], baseRadius: 2, capPoint: [0, 2, 0], capRadius: 0 });
Attributes
 ReqNameType(s)Description
RWYbasePointVectorXYZDefines the location of the center of the cone's base end.
RWYbaseRadiusfloatDefines the radius of the cone's base end.
RWYcapPointVectorXYZDefines the location of the center of the cone's cap end.
RWYcapRadiusfloatDefines the radius of the cone's cap end. If this is non-zero, it technically ceases to be a cone and instead becomes a frustum.
RWNopenbooleanIf true, the base and the cap are left open, yielding a hollow cone.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Cone, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Cone, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Cone, this is always true.
RO solidbooleanIf true, the shape is solid. For a Cone, this is always true.

Cubic

A Cubic is a third-order polynomial surface. It has a single required attribute like the rest of the polynomial types, coefficients, which is an array of 20 floats.

Attributes
 ReqNameType(s)Description
RWYcoefficients[float]An array of 20 floats that act as the coefficients of a third-order polynomial.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Cubic, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Cubic, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Cubic, this is always false.
RO solidbooleanIf true, the shape is solid. For a Cubic, this is always true.

Cylinder

The Cylinder type produces a solid cylinder by default and defined by the coordinates of the centers of its two circular ends, basePoint and capPoint, plus the radius of both. If the open attribute is true, the end caps are omitted and the interior is hollow, leaving an infinitely thin tube.

If it is being used as a component in a Blob, the strength attribute can be used to assign a field strength to the cylinder.

The following code produces the example at right:

var obj = new Cylinder({ basePoint: [0, -2, 0], capPoint: [0, 2, 0], radius: 2, });
Attributes
 ReqNameType(s)Description
RWYbasePointVectorXYZDefines the center of the base end of the cylinder.
RWYcapPointVectorXYZDefines the center of the cap end of the cylinder.
RWYradiusfloatDefines the radius of the cylinder.
RWNopenbooleanIf true, the cap and base planes are are eliminating, yielding a hollow tube.
RWNstrengthfloatDefines the field strength of the cylinder. This is only used when the cylinder is a component of a Blob object.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Cylinder, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Cylinder, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Cylinder, this is always true.
RO solidbooleanIf true, the shape is solid. For a Cylinder, this is always true.

Difference

The Difference type is one of the four CSG operations. It has two required attributes. The positiveComponent is a single object (which may be another composite CSG object) from which the array of objects in negativeComponents is subtracted. In this case, one sphere has been subtracted from another, producing a sphere with a dish-shaped depression in one side.

var obj1 = new Sphere({ center: [1,0,-2], radius: 1.5 }); var obj2 = new Sphere({ center: [3,0,-1], radius: 1.5 }); var diff = new Difference({ positiveComponent: obj1, negativeComponents: [obj2] });
Attributes
 ReqNameType(s)Description
RWYnegativeComponentsArrayThis is an array of objects to subtract from the positiveComponent.
RWYpositiveComponentPrimitiveThis is the single base object from which the object(s) in the negativeComponents array are subtracted.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Difference, this is always true.
RO finitebooleanIf true, the shape is finite in extent. For a Difference, this is always false.
RO solidbooleanIf true, the shape is solid. For a Difference, this is always true.

Disc

The Disc type is a two-dimensional circular disc defined by its center, radius, and normal. As in the example below, it is possible to turn it into a washer-like ring by specifying a non-zero holeRadius.

var obj = new Disc({ center: [0, 0, 0], radius: 2, holeRadius: 1, normal: [0, 1, 0] });
Attributes
 ReqNameType(s)Description
RWYcenterVectorXYZThis is the center point of the disc.
RWYnormalVectorXYZThis defines the normal or orientation of the disc in space.
RWYradiusfloatDefines the radius of the disc.
RWNholeRadiusfloatIf supplied and non-zero, defines the radius of the hole in the center of the disc.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Disc, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Disc, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Disc, this is always true.
RO solidbooleanIf true, the shape is solid. For a Disc, this is always false.

HeightField

A HeightField takes a bitmapped graphics file and converts it into a triangle mesh in which the height of each point is determined by either the intensity of the corresponding pixel or, for indexed graphics, its index number. It is frequently used for creating landscapes.

The resulting mesh fits into a unit cube. The optional waterLevel attribute, set to a value in the unit interval (0.0 - 1.0), progressively hides a portion of the mesh to simulate water. (It does not provide a water plane; you will have to do that yourself.) A waterLevel value of 0.0 reveals the entire mesh, while a value of 1.0 hides all of it; intermediate values hide only part of it.

For complete details on the graphics formats accepted, see the POV-Ray documentation. The example here uses a 16-bit greyscale PNG file.

var obj = new HeightField({ source: "hf_demo.png", waterLevel: 0.4, smooth: true, texture: yellow }); var xform = new Matrix("translate", -0.5, -0.5, -0.5); obj.transform = xform.xMatrix(new Matrix("scale", 6, 3, 6));
Attributes
 ReqNameType(s)Description
RWYsourceSDL
string
Defines the source of the points that comprise the height field. This may be either an SDL function or the path to a graphics file.
RWNgammafloat
string
Defines the gamma value to be used in interpreting an image file. This may be either a float or the string "sRGB".
RWNhfTypestringIf source is a graphics file, the hfType attribute declares the file format, which must be one of "exr", "gif", "hdr", "iff", "jpeg", "pgm", "png", "pot", "ppm", "sys", "tga", and "tiff".
RWNhierarchybooleanIf false, turn off the internal bounding hierarchy.
RWNpremultipliedbooleanSpecifies whether the file is stored in premultiplied associated or non-premultiplied straight alpha format, overriding the file format specific default. This keyword has no effect on files without an alpha channel.
RWNsmoothbooleanIf true, POV-Ray will manipulate the surface normals of the generated triangles to create a smoother-looking surface.
RWNwaterLevelfloatDefines the point below which the height field is hidden. This defaults to 0.0, which corresponds to the bottom of the height field, i.e., nothing is hidden. At the other extreme, 1.0 will cause the entire height field to be hidden. Note that this does not create a plane representing water; you'll have to do that manually.
RO csgbooleanIf true, the primitive is a composite CSG container. For a HeightField, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a HeightField, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a HeightField, this is always true.
RO solidbooleanIf true, the shape is solid. For a HeightField, this is always true.

Intersection

The Intersection type is one of the four CSG operations. Like all of the CSG operations other than Difference, it has a single mandatory attribute, components, which is an array of objects. The result is their set-theoretical intersection, i.e., the space in which all of the components overlap.

In the example, we have taken the intersection of two overlapping spheres, yielding an object shaped like the lens of a magnifying glass.

var obj1 = new Sphere({ center: [1,0,-2], radius: 1.5 }); var obj2 = new Sphere({ center: [3,0,-1], radius: 1.5 }); var intersection = new Intersection({ components: [ obj1, obj2 ] });
Attributes
 ReqNameType(s)Description
RWYcomponents[Primitive]An array of objects whose intersection will produce the resulting object.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Intersection, this is always true.
RO finitebooleanIf true, the shape is finite in extent. For a Intersection, this is always false.
RO solidbooleanIf true, the shape is solid. For a Intersection, this is always true.

IsoSurface

Short of the dubious goal of writing a JavaScript-to-SDL compiler, complete independence from POV-Ray's Scene Description Language is not possible in a few cases. The IsoSurface object is one of these because its sole required attribute, source, is a function or functions written in SDL. It's worth the effort of understanding, however, because the definition of isosurfaces is one of POV-Ray's most powerful features. For complete details, see the POV-Ray docs.

In this example, we're just grabbing an example from the POV-Ray docs to serve as the source attribute. Don't forget to include the leading '&' that tells CephaloPOV that it's getting SDL code instead of an ordinary string.

var obj = new IsoSurface({ source: "&function{fn_A(x,y,z) + " + "pow(Blob_Threshold,(fn_B(x,y,z) + Strength))}" });
Attributes
 ReqNameType(s)Description
RWYsourceSDLThis is a string containing the SDL function code which defines the surface.
RWNaccuracyfloatDefines the amount of subdivision POV-Ray performs to find the surface, with lower values being more accurate. Defaults to 0.001.
RWNcontainedBySphere
Box
Defines a Sphere or Box which determines the portion of the (potentially infinite) surface that POV-Ray will render. By default, this is a Box with corners at [1, 1, 1] and [-1, -1, -1].
RWNevaluate[float]This is an array of three floats that optionally guides POV-Ray in dynamically adapting maxGradient. See the official POV-Ray documentation for details.
RWNmaxGradientfloatRendering will be faster if POV-Ray knows the maximum gradient of the source function. The maxGradient value defaults to 1.1, but if this too low, holes and other imperfections may appear, and POV-Ray will emit a warning telling you the maximum gradient it found so that you can manually update this value. Beware of raising the value beyond the actual maximum gradient, as this will slow down the render.
RWNmaxTraceinteger
string
When used as part of a CSG object, this determines the maximum number of surfaces to look for when constructing the final CSG object. By default, only the containedBy object is examined. For complete accuracy at the expense of speed, use the string "all_intersections".
RWNopenbooleanIf true, the boundaries where the isosurface intersects with the containedBy object will be left open.
RWNthresholdfloatThe surface appears where the value of source equals this value, which defaults to 0.
RO csgbooleanIf true, the primitive is a composite CSG container. For a IsoSurface, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a IsoSurface, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a IsoSurface, this is always true.
RO solidbooleanIf true, the shape is solid. For a IsoSurface, this is always true.

JuliaFractal

The JuliaFractal is a three-dimensional slice of a four-dimensional Julia fractal set. See the POV-Ray docs for a little more detail. The CephaloPOV interface follows the POV-Ray model quite closely, the major difference being that POV-Ray's anonymous algebra type and function type parameters are combined in type.

var obj = new JuliaFractal({ juliaParam: [-0.083, 0.0, -0.83, -0.025], type: "quaternion:sqr", maxIter: 8, precision: 15 });
Attributes
 ReqNameType(s)Description
RWYjuliaParamVectorXYZWThis is the standard julia parameter, p, in f(h) + p.
RWYtypestringSpecifies the type of julia fractal formula used. The legal values are:
Julia Fractal Types
hypercomplex:acos
hypercomplex:acosh
hypercomplex:asin
hypercomplex:atan
hypercomplex:atanh
hypercomplex:cos
hypercomplex:cosh
hypercomplex:cube
hypercomplex:exp
hypercomplex:ln
hypercomplex:pwr
hypercomplex:reciprocal
hypercomplex:sin
hypercomplex:sinh
hypercomplex:sqr
hypercomplex:tan
hypercomplex:tanh
quaternion:cube
quaternion:sqr
RWNdistancefloatSpecifies the distance of the slice from the origin. Defaults to 0.
RWNmaxIterintegerDetermines the number of iterations used to find the surface of the fractal, with higher values being more accurate but slower to render. The default is 20.
RWNpowerVectorXYFor the hypercomplex:pwr formula, this VectorXY contains the X and Y exponents used in the calculations. Has no effect on other formula types.
RWNprecisionintegerDetermines the accuracy of the calculations for finding the surface of the julia set. The default is 20. Higher values result in greater accuracy but longer rendering times.
RWNsliceVectorXYZWSpecifies the 3D slice through 4D space used to view the fractal. Defaults to [0, 0, 0, 1].
RO csgbooleanIf true, the primitive is a composite CSG container. For a JuliaFractal, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a JuliaFractal, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a JuliaFractal, this is always true.
RO solidbooleanIf true, the shape is solid. For a JuliaFractal, this is always true.

Lathe

The Lathe object is a surface of revolution created by sweeping a spline around the y-axis, centered at the origin. The resulting object is solid, but the spline will not produce a closed curve unless the first and last points are the same.

A Lathe is much more flexible than the other surface of revolution object, Sor, but it is also substantially slower to render.

var obj = new Lathe({ points: [ [0, -1.2], [1, -1.2], [1, -0.8], [0.8, -0.6], [0.8, -0.4], [1, -0.4], [1, -0.2], [0.8, -0.2], [0.8, 0], [1, 0], [1, 0.2], [0.8, 0.2], [0.6, 0.8], [0.6, 1.2], [0.8, 1.2], [0.8, 1.4], [0, 1.4] ], type: "linearSpline" });
Attributes
 ReqNameType(s)Description
RWYpointsVectorXYAn array of points defining the spline. Linear splines require at least two points, quadratic splines require at least three, and cubic and bezier splines require at least four.
RWYtypestringDetermines the type of spline used to define the profile. Legal types are "bezierSpline", "cubicSpline", "linearSpline", and "quadraticSpline".
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Lathe, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Lathe, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Lathe, this is always true.
RO solidbooleanIf true, the shape is solid. For a Lathe, this is always true.

LightSource

TODO

Attributes
 ReqNameType(s)Description
RWYcolorColorSpecifies the color of the light source.
RWYlocationVectorXYZSpecifies the location of the light source.
RWYtypestringDetermines the type of the light. The legal values are "cylinder", "point", and "spotlight".
RWNadaptivefloatUsed with area lights. If defind, POV-Ray will use adaptive sampling in an attempt to speed up rendering. Higher values are more accurate.
RWNareaIlluminationbooleanIf true, the experimental support in POV-Ray 3.7 for full area light diffuse and specular illumination is enabled.
RWNareaLightbooleanIf true, the light becomes an area light, and axis1, axis2, size1, and size2 must be defined.
RWNaxis1VectorXYZWhen areaLight is true, axis1 defines the orientation of the area light along one axis.
RWNaxis2VectorXYZWhen areaLight is true, axis2 defines the orientation of the area light along one axis.
RWNcircularbooleanUsed with area lights. If true, the default rectilinear grid is modified to approximate a circle or ellipse.
RWNfadeDistancefloatDefines the distance at which the light will be at full intensity.
RWNfadePowerfloatDefines the rate at which light intensity decreases with distance beyond fadeDistance. A value of 1 is linear, 2 is quadratic, and so on.
RWNfallofffloatIf specified, falloff describes a larger cone than radius within which the light fades from its original intensity to nothing. Note that this will still cast sharp shadows.
RWNjitterbooleanUsed with area lights. If true, the positions of the lights are randomly moved during rendering so that banding effects are minimized. Should not be used with animations.
RWNlooksLikePrimitiveAssigns an object (with an implicit noShadow flag) to act as the physical source of the light.
RWNmediaAttenuationbooleanIf true, the light will be attenuated by passing through media. The default is false.
RWNmediaInteractionbooleanIf true (the default), the light will interact with media.
RWNorientbooleanUsed with area lights, and causes the array of lights to be oriented toward every surface being tested. The orient flag can only be used along with circular when both axes are of equal length and use an equal number of samples.
RWNparallelbooleanIf true, all of the light rays will be parallel to the line between location and pointAt. This is useful for simulating very distant light sources like the sun, but be aware that shadows cease to work behind the light plane.
RWNpointAtVectorXYZSpecifies the point the spotlight is aimed at.
RWNprojectedThroughPrimitiveSpecifies an object through which the light rays must pass in order to be visible.
RWNradiusfloatSpecifies the angle of the cone of light produced by a spotlight.
RWNshadowlessbooleanIf true, the light will neither cast shadows nor cause highlights.
RWNsize1floatWhen areaLight is true, size1 defines the number of rows of lights.
RWNsize2floatWhen areaLight is true, size2 defines the number of columns of lights.
RWNtightnessfloatThe tightness attribute is a number between 0 and 100 that modifies the relationship between radius and falloff. Counterintuitively, lower values produce a sharper, brighter spotlight and higher values produce a dimmer, softer spotlight. To exercise complete control over the spotlight with tightness alone, set radius = 0 and falloff = 90.
RO csgbooleanIf true, the primitive is a composite CSG container. For a LightSource, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a LightSource, this is always true.
RO finitebooleanIf true, the shape is finite in extent. For a LightSource, this is always true.
RO solidbooleanIf true, the shape is solid. For a LightSource, this is always false.

Merge

The Merge type is one of the four CSG operations. Like all of the CSG operations other than Difference, it has a single mandatory attribute, components, which is an array of objects. The result is their set-theoretical union, which is different from the original ad hoc collection of objects in that it can be treated as a single object and tranformed and textured as a whole, as well as participating in further CSG operations.

A Merge differs from the otherwise identical Union by eliminating the hidden inner surfaces. This doesn't matter with opaque objects, of course, but it is often useful when creating transparent or translucent objects.

In the example, we have merged two spheres, resulting in a single object that looks, um, exactly like two spheres.

var obj1 = new Sphere({ center: [1,0,-2], radius: 1.5 }); var obj2 = new Sphere({ center: [3,0,-1], radius: 1.5 }); var merge = new Merge({ components: [ obj1, obj2 ] });
Attributes
 ReqNameType(s)Description
RWYcomponentsArrayAn array of objects to merge.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Merge, this is always true.
RO finitebooleanIf true, the shape is finite in extent. For a Merge, this is always false.
RO solidbooleanIf true, the shape is solid. For a Merge, this is always true.

Mesh

TODO

var obj = new PlaceholderObj({ // TODO });
Attributes
 ReqNameType(s)Description
RWYtriangles[Triangle]The array of Triangles comprising the mesh.
RWNhierarchybooleanIf false, turn off the internal bounding hierarchy.
RWNinsideVectorVectorXYZFor the Mesh to be solid, it must be completely closed and have a defined insideVector.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Mesh, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Mesh, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Mesh, this is always true.
RO solidbooleanIf true, the shape is solid. For a Mesh, this is always false.

Ovus

The Ovus type is one of POV-Ray's more interesting and versatile geometric primitives. It consists of two spheres defined by bottomRadius and topRadius such that the center of the top sphere is positioned on the top of the bottom sphere, and then a smooth curved surface connects the two. The center of the bottom sphere is at the origin, and the centers of both spheres are aligned along the y-axis.

In the example code below, the result is the egg-like shape to the right, but a wide variety of other shapes can be constructed with it.

var obj = new Ovus({ bottomRadius: 2, topRadius: 1 });
Attributes
 ReqNameType(s)Description
RWYbottomRadiusfloatSets the radius of the bottom sphere.
RWYtopRadiusfloatSets the radius of the top sphere.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Ovus, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Ovus, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Ovus, this is always true.
RO solidbooleanIf true, the shape is solid. For a Ovus, this is always true.

Parametric

Along with IsoSurface, the Parametric type is one of the places where CephaloPOV cannot shield you from the POV-Ray Scene Description Language, or at least a subset of it. However, also like IsoSurface, the Parametric type is one of POV-Ray's most powerful features, so it's well worth the effort of understanding the POV-Ray docs and a few online tutorials unless you're especially math-averse. (And if so, do you know where you are?)

The short version is that Parametric objects are hollow surfaces defined by three functions that map the UV-plane to explicit xyz-coordinates whereas IsoSurface objects are solid and have surfaces implicitly defined by a single function yielding a potential field. Ergo, in place of the single source attribute of the IsoSurface, a Parametric has an attribute for each of the three axes, funcX, funcY, and funcZ.

var p2 = 2 * Math.PI; var obj = new Parametric({ funcX: "&function { 1.0 * (1 - 0.5 * v / pi) " + "* sin(5 * v + 0.5 *pi) " + "* (1 - cos(u)) + 0.2 * sin(5 * v + 0.5 * pi) }", funcY: "&function { 8 * 0.5 * v / pi + 1.0 " + "* (1 - 0.5 * v / pi) * sin(u) }", funcZ: "&function { 1.0 * (1 - 0.5 * v / pi) " + "* cos(5 * v + 0.5 * pi) " + * (1 - cos(u)) + 0.2 * cos(5 * v + 0.5 * pi) }", uv1: [0, 0], uv2: [p2, p2], accuracy: 0.0035, precomputeDepth: 18, precomputeX: true, precomputeY: true, precomputeZ: true, maxGradient: 10, containedBy: new Box({ corner1: [-p2, -p2, -p2], corner2: [p2, 8/3 *p2, p2], }), }); obj.transform = new Matrix("scale", 0.4, 0.4, 0.4); obj.transform = new Matrix("rotate", 0, 90, 0);
Attributes
 ReqNameType(s)Description
RWYfuncXSDLDetermines the X coordinate of the surface.
RWYfuncYSDLDetermines the Y coordinate of the surface.
RWYfuncZSDLDetermines the Z coordinate of the surface.
RWYuv1VectorUVSpecifies one corner of the UV plane to which the surface is mapped.
RWYuv2VectorUVSpecifies the other corner of the UV plane to which the surface is mapped.
RWNaccuracyfloatDefines the amount of subdivision POV-Ray performs to find the surface, with lower values being more accurate. Defaults to 0.001.
RWNcontainedBySphere
Box
Defines a Sphere or Box which determines the portion of the (potentially infinite) surface that POV-Ray will render. By default, this is a Box with corners at [1, 1, 1] and [-1, -1, -1].
RWNmaxGradientfloatRendering will be faster if POV-Ray knows the maximum gradient of the surface functions. The maxGradient value defaults to 1.1, but if this too low, holes and other imperfections may appear, and POV-Ray will emit a warning telling you the maximum gradient it found so that you can manually update this value. Beware of raising the value beyond the actual maximum gradient, as this will slow down the render.
RWNprecomputeDepthintegerIf defined, precomputeDepth can speed up rendering at the expense of memory. The maximum value is 20. At least one of precomputeX, precomputeY, or precomputeZ must be true.
RWNprecomputeXbooleanEnables precalculation of the X coordinate during subdivision of parametric surfaces. precomputeDepth must also be defined.
RWNprecomputeYbooleanEnables precalculation of the Y coordinate during subdivision of parametric surfaces. precomputeDepth must also be defined.
RWNprecomputeZbooleanEnables precalculation of the Z coordinate during subdivision of parametric surfaces. precomputeDepth must also be defined.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Parametric, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Parametric, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Parametric, this is always true.
RO solidbooleanIf true, the shape is solid. For a Parametric, this is always true.

Plane

Arguably POV-Ray's simplest primitive, the Plane is an infinite solid dividing all space into two halves. It is defined by a distance from the origin and a normal which determines the orientation of its surface. It provides a convenient infinite ground plane, of course, but because it creates a solid half-surface, you can use a CSG Intersection of planes to create complex shapes like solid polyhedra.

In the example below, the plane is oriented perpendicularly to the y-axis at the origin. Its infinite extent is amusingly clear in the rendering to the right, where our standard demonstration stage looks like it has been caught in a flood!

var obj = new Plane({ distance: 0, normal: [0, 1, 0] });
Attributes
 ReqNameType(s)Description
RWYdistancefloatSpecifies the distance the plane lies from the origin along the normal vector. This is multiplied by the normal, so if distance is 2 and normal is [0, 2, 0], the plane will lie 4 units from the origin.
RWYnormalVectorXYZDefines the surface normal of the plane, i.e., a vector that points up perpendicularly from the surface of the plane.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Plane, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Plane, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Plane, this is always false.
RO solidbooleanIf true, the shape is solid. For a Plane, this is always true.

Poly

The Poly type offers a generic interface to create polynomial surfaces of orders 2 to 35. You must specify the order of the polynomial and then supply its coefficients, the number of which depends on the order:

n = ((order + 1) * (order + 2) * (order + 3)) / 6;

(CephaloPOV will helpfully throw a fatal error if you get the number of coefficients wrong.)

The example below, adapted from POV-Ray's shapesq.inc file, is a variant of a lemniscate.

var obj = new Poly({ order: 6, coefficients: [ 4, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ], texture: yellow }); obj.transform = new Matrix("scale", 2, 2, 2);
Attributes
 ReqNameType(s)Description
RWYcoefficients[float]An array defining the coefficients of the polynomial. The number of coefficients required is equal to ((order + 1) * (order + 2) * (order + 3)) / 6.
RWYorderintegerSpecifies the order of the polynomial. Must be in the range 2 to 35.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Poly, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Poly, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Poly, this is always false.
RO solidbooleanIf true, the shape is solid. For a Poly, this is always true.

Polygon

Another versatile two-dimensional primitive, the Polygon type is defined by it's sole points parameter, which is an array of VectorXY points listing the vertices of an arbitrary polygon on the XY-plane. For a simple polygon, a line will automatically connect the first and last points. If the first point of the polygon is repeated, subsequent points create an additional polygon which, if it is enclosed in the first (or another) polygon, defines a hole in it.

In the example code below, two rectangles are defined with the second being a hole in the first.

var obj = new Polygon({ points: [[-2, 2], [2, 2], [2, -2], [-2, -2], [-2, 2], [-1, 1], [1, 1], [1, -1], [-1, -1], [-1, 1]], });
Attributes
 ReqNameType(s)Description
RWYpoints[VectorXY]This is an array of at least three VectorXY objects defining the vertices of the polygon.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Polygon, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Polygon, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Polygon, this is always true.
RO solidbooleanIf true, the shape is solid. For a Polygon, this is always false.

Polynomial

The Polynomial type is another arbitrary polynomial shape object that provides an alternative to the Poly type, and like it, it must have an order in the range 2–35. The coefficients are encoded in an array of VectorXYZW where the x, y, and z attributes signify the powers of the respective indeterminates and w is repurposed to contain the coefficient.

As noted in the description of Poly, the order determines the number of coefficients thus:

n = ((order + 1) * (order + 2) * (order + 3)) / 6;

In the example shown, a sphere is produced by a second-order polynomial.

var obj = new Polynomial({ order: 2, coefficients: [ [2, 0, 0, 1], [0, 2, 0, 1], [0, 0, 2, 1], [0, 0, 0, -1] ] });
Attributes
 ReqNameType(s)Description
RWYcoefficients[VectorXYZW]An array of VectorXYZW defining the coefficients of the polynomial. The choice of VectorXYZW is a bit of a convenience hack as it doesn't encode a 4D cartesian point. Instead, the X, Y, and Z values specify the corresponding powers of the coefficient and W specifies the value. The members of the array can be specified in any order.
RWYorderintegerSpecifies the order of the polynomial. Must be in the range 2 to 35.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Polynomial, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Polynomial, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Polynomial, this is always false.
RO solidbooleanIf true, the shape is solid. For a Polynomial, this is always true.

Prism

The Prism type is the three-dimensional analogue of the Polygon. It sweeps the shape defined by the array of VectorXY in the points parameter along the y-axis from height1 to height2. The points may define multiple sub-polygons provided that each polygon is closed by repeating the first point as the last.

Unlike Polygon.points, Prism.points may specify more than just simple linear splines depending on the value of type.

The example below uses the same points argument as the example for the Polygon.

var obj = new Polygon({ height1: -2, height2: 2, type: "linearSpline", points: [[-2, 2], [2, 2], [2, -2], [-2, -2], [-2, 2], [-1, 1], [1, 1], [1, -1], [-1, -1], [-1, 1]], });
Attributes
 ReqNameType(s)Description
RWYheight1floatSpecifies the Y coordinate of the top of the prism.
RWYheight2floatSpecifies the Y coordinate of the bottom of the prism.
RWYpointsArrayThe array of spline points to be swept along the Y axis. This can specify multiple sub-shapes: to close a shape, simply repeat the first coordinate. When using any type other than linearSpline, all shapes must be closed.
RWYtypestringSpecifies the spline type used for the prism. The legal values are "bezierSpline", "conicSweep", "cubicSpline", "linearSpline", "linearSweep", and "quadraticSpline".
RWNopenbooleanIf true, the top and bottom of the prism are left open.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Prism, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Prism, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Prism, this is always true.
RO solidbooleanIf true, the shape is solid. For a Prism, this is always true.

Quadric

The Quadric type is an optimized second-order polynomial shape. Its sole required attribute is coefficients, an array of 10 floats.

The example shown is an infinite hyperboloid aligned with the y-axis.

var obj = new Quadric({ coefficients: [ 1, -1, 1, 0, 0, 0, 0, 0, 0, -1 ], texture: yellow });
Attributes
 ReqNameType(s)Description
RWYcoefficientsArrayAn array of 10 floats defining the coefficients of a second-order polynomial.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Quadric, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Quadric, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Quadric, this is always false.
RO solidbooleanIf true, the shape is solid. For a Quadric, this is always true.

Quartic

The Quartic type is an optimized fourth-order polynomial shape. Its sole required attribute is coefficients, an array of 35 floats.

The example here is a torus, albeit one that renders more slowly than the optimized, dedicated Torus type.

var obj = new Quartic({ coefficients: [ 1, 0, 0, 0, 2, 0, 0, 2, 0, -104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 56, 0, 0, 0, 0, 1, 0, -104, 0, 784 ], texture: yellow }); obj.transform = new Matrix("scale", 0.2, 0.2, 0.2);
Attributes
 ReqNameType(s)Description
RWYcoefficientsArrayAn array of 35 floats defining the coefficients of a fourth-order polynomial.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Quartic, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Quartic, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Quartic, this is always false.
RO solidbooleanIf true, the shape is solid. For a Quartic, this is always true.

Sor

The Sor object, in addition to being an example of how camelCase breaks down when forced to ingest acronyms, is a simpler and faster form of a surface of revolution than the Lathe object. It supports only a single type of smoothly interpolated curve which cannot be closed and can have only a single radius (x) value at any given point (y), i.e., it's a normal mathematical function. However, unlike a Lathe, a Sor has an open attribute which, if true, eliminates the normal endcaps and yields a hollow shape.

var obj = new Sor({ points: [ [0, -1.4], [0, -1.3], [1, -1.2], [1, -0.8], [0.8, -0.6], [0.8, -0.5], [1, -0.4], [1, -0.3], [0.8, -0.2], [0.8, 0.1], [1, 0.2], [1, 0.3], [0.8, 0.4], [0.6, 0.8], [0.6, 1.2], [0.8, 1.3], [0.8, 1.4], [0, 1.5], [0, 1.6] ] });
Attributes
 ReqNameType(s)Description
RWYpointsVectorXYAn array of at least two points which define the open curve used to generate the surface.
RWNopenbooleanIf true, the base and the cap are left open, yielding a hollow surface of revolution.
RWNsturmbooleanIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Sor, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Sor, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Sor, this is always true.
RO solidbooleanIf true, the shape is solid. For a Sor, this is always true.

Sphere

The Sphere is defined by the coordinates of its center and the measure of its radius. The example at right was created by the following code:

var obj = new Sphere({ center: [0, 0, 0], radius: 2 });

The optional strength parameter does nothing with an independent Sphere, but when the object is part of a Blob, it sets the field strength.

Attributes
 ReqNameType(s)Description
RWYcenterVectorXYZDefines the center point of the sphere.
RWYradiusfloatSpecifies the radius of the sphere.
RWNstrengthfloatIf and only if the Sphere is being used as a blob component, strength is a float defining its field strength.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Sphere, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Sphere, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Sphere, this is always true.
RO solidbooleanIf true, the shape is solid. For a Sphere, this is always true.

SphereSweep

A SphereSweep is a shape consisting of the space occupied by a sphere moving along a spline. The radius of the sphere can vary over time. It is defined by an array of spheres, with a minimum of two for a linear spline or four spheres for a bezier spline or a cubic spline.

For the sake of brevity, the example consists of a linear spline arranged in a rectangle with two different sizes of spheres acting as control points, but you can construct arbitrarily complicated shapes with a SphereSweep.

var obj = new SphereSweep({ spheres: [ new Sphere({ center: [-1, 1, -1], radius: 0.25 }), new Sphere({ center: [-1, 1, 1], radius: 0.5 }), new Sphere({ center: [1, -1, 1], radius: 0.25 }), new Sphere({ center: [1, -1, -1], radius: 0.5 }), new Sphere({ center: [-1, 1, -1], radius: 0.25 }), ], type: "linearSpline" });
Attributes
 ReqNameType(s)Description
RWYspheresArrayThe array of Spheres whose positions are interpolated to create the sweep.
RWYtypestringSets the spline type to be used for the sweep. The legal values are "bezierSpline", "cubicSpline", and "linearSpline".
RWNtolerancefloatDefines the depth tolerance used for intersection calculations. The default value, 0.000001, should be adequate in most cases. If imperfections appear on the surface of the sweep, try increasing it to 0.0001.
RO csgbooleanIf true, the primitive is a composite CSG container. For a SphereSweep, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a SphereSweep, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a SphereSweep, this is always true.
RO solidbooleanIf true, the shape is solid. For a SphereSweep, this is always true.

Superellipsoid

The Superellipsoid type implements what is more properly known as a superquadric ellipsoid whose shape can vary from a cube with rounded edges to fat, egg-like cylinders. It is defined solely by two float parameters, e and n, the so-called east-west and north-south exponents, respectively. It occupies roughly the same space as a Box with corners at [1, 1, 1] and [-1, -1, -1].

As the example code and rendering indicate, when e and n have the same value, the result is a cube with rounded edges. When both values reach 1.0, the result is equivalent to a unit sphere.

var obj = new Superellipsoid({ e: 0.25, n: 0.25 });
Attributes
 ReqNameType(s)Description
RWYefloatDefines the so-called east-west exponent.
RWYnfloatDefines the so-called north-south exponent.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Superellipsoid, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Superellipsoid, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Superellipsoid, this is always true.
RO solidbooleanIf true, the shape is solid. For a Superellipsoid, this is always true.

Text

The Text type is very similar to the Prism type, the main difference being that instead of specifying a spline yourself, you hand it a string and the pathname of a TrueType font or a TrueType collection from which the first font will be used.

Fonts, even professionally-designed ones, vary in their obedience to conventions, so some experimentation is often needed. In most cases, individual characters will be one unit high. The extruded text will begin at the origin and run in the +x direction along the x-axis. The front of the text will be parallel to the xy-plane and the extrusion will go in the +z direction.

var obj = new Text({ displayText: "CPOV", font: "BebasNeueBold.ttf", fontType: "ttf", thickness: 0.25, offset: 0 }); obj.transform = new Matrix("scale", 2, 2, 2); obj.transform = new Matrix("translate", 0, 0, -1);
Attributes
 ReqNameType(s)Description
RWYdisplayTextstringThis contains the text to be rendered.
RWYfontstringThe filename of the font.
RWYfontTypestringSpecifies the file format of the font being used. Legal values are "ttc", and "ttf".
RWYoffsetfloatSpecifies extra space to be placed between characters, 0 for none.
RWYthicknessfloatSpecifies the front-to-back thickness of the extruded character shapes.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Text, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Text, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Text, this is always true.
RO solidbooleanIf true, the shape is solid. For a Text, this is always true.

Torus

The Torus type specifies a torus with its major and minor radii. If you think of a torus as the surface described by a smaller two-dimensional ring swept perpendicularly to a larger ring, the majorRadius is the radius of the larger ring, and the minorRadius is the radius of the smaller ring.

The example code and rendering demonstrates a Torus with a minor radius of 0.5 units and a major radius of 2 units.

var obj = new Torus({ minorRadius: 0.5, majorRadius: 2 });
Attributes
 ReqNameType(s)Description
RWYmajorRadiusfloatDefines the major radius of the torus, which is the circle along which the perpendicular circle defined by minorRadius is swept.
RWYminorRadiusfloatDefines the minor radius of the torus, which is the radius of its cross section.
RWNsturmfloatIf true, POV-Ray will use the slower but more accurate Sturmian root solver. Use this if the surface exhibits holes or other imperfections.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Torus, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Torus, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Torus, this is always true.
RO solidbooleanIf true, the shape is solid. For a Torus, this is always true.

Triangle

The Triangle type describes a triangular patch that can be used independently or as part of a mesh. There are two kinds of triangles in POV-Ray, triangle and smooth_triangle, and both are subsumed in CephaloPOV's Triangle.

A (plain) triangle has only three required attributes, corner1, corner2, and corner3, all VectorXYZ objects with an obvious purpose.

A smooth triangle takes four more attributes. The first is smooth, which must be true, in addition to which normal1, normal2, and normal3 must be set. This enables the use of Phong shading. If smooth is false, the triangle will be output as a plain triangle. Toggling between the two can be useful for speeding up preview renders or effects in animations.

var obj = new Triangle({ corner1: [ -1, -1, -1 ], corner2: [ 1, -1, -1 ], corner3: [ 0, 1, 1 ], texture: yellow });
Attributes
 ReqNameType(s)Description
RWYcorner1VectorXYZDefines the first corner of the triangle.
RWYcorner2VectorXYZDefines the second corner of the triangle.
RWYcorner3VectorXYZDefines the third corner of the triangle.
RWNnormal1VectorXYZSpecifies the surface normal for corner1.
RWNnormal2VectorXYZSpecifies the surface normal for corner2.
RWNnormal3VectorXYZSpecifies the surface normal for corner3.
RWNsmoothbooleanIf smooth is true and normal1...3 are defined, the triangle will be output as a smooth triangle.
RWNtexturesVectorXYZTODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec tellus quis turpis pretium condimentum ut eget neque. Integer pharetra imperdiet elit, eu malesuada tortor.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Triangle, this is always false.
RO csgOperandbooleanIf true, the object is not actually a POV-Ray primitive object, but CephaloPOV treats it as similar to one in many ways. For a Triangle, this is always false.
RO finitebooleanIf true, the shape is finite in extent. For a Triangle, this is always true.
RO solidbooleanIf true, the shape is solid. For a Triangle, this is always false.

Union

The Union type is one of the four CSG operations. Like all of the CSG operations other than Difference, it has a single mandatory attribute, components, which is an array of objects. The result is their set-theoretical union, which is different from the original ad hoc collection of objects in that it can be treated as a single object and tranformed and textured as a whole, as well as participating in further CSG operations.

A Union differs from the otherwise identical Merge by retaining the hidden inner surfaces. This doesn't matter with opaque objects, of course, but it is often useful when creating transparent or translucent objects.

In the example, we have merged two spheres, resulting in a single object that looks, um, exactly like two spheres.

var obj1 = new Sphere({ center: [1,0,-2], radius: 1.5 }); var obj2 = new Sphere({ center: [3,0,-1], radius: 1.5 }); var union = new Union({ components: [ obj1, obj2 ] });
Attributes
 ReqNameType(s)Description
RWYcomponentsArrayThis is the array of objects to be combined by the CSG Union.
RWNsplitUnionbooleanIf the composite object lacks holes, setting splitUnion to false can speed up rendering. Defaults to true.
RO csgbooleanIf true, the primitive is a composite CSG container. For a Union, this is always true.
RO finitebooleanIf true, the shape is finite in extent. For a Union, this is always false.
RO solidbooleanIf true, the shape is solid. For a Union, this is always true.

Texture Classes

POV-Ray's texture system, which governs the appearance of the surface of objects, is more complicated than the objects themselves. It's not especially hard to use; there's just a lot of it. CephaloPOV attempts to wrap it in as straightforward a set of JavaScript classes as possible, but there's no hiding the underlying complexity. Moreover, as with the geometric primitives, there are some features of the texture system that are impossible to access without resorting to SDL. That said, CephaloPOV's wrappers capture well over 95% of its functionality and offers escape routes into SDL for the remaining 5%.

Optional Libraries

CephaloPOV includes a small but growing number of optional standard libraries, where "standard" just means they ship with CephaloPOV and there's a special method to require them using handy aliases:

var easing = cpov.requireOptLib("easingFuncs"); var colors = cpov.requireOptLib("colors.inc");

Some of the libraries are ports of POV-Ray include files to their JavaScript equivalents. These are generally loaded using their POV-Ray names, like colors.inc. Others provide useful functionality like Robert Penner's easing functions.

colors.inc

This is a straight port of the color names and RGB values in POV-Ray's standard include file, colors.inc.

var colors = cpov.requireOptLib("colors.inc");

Importing this library makes the following color values available:

aquamarine
bakersChoc
black
blue
blueViolet
brass
brightGold
bronze2
bronze
brown
cadetBlue
clear
coolCopper
copper
coral
cornflowerBlue
cyan
darkBrown
darkGreen
darkOliveGreen
darkOrchid
darkPurple
darkSlateBlue
darkSlateGray
darkSlateGrey
darkTan
darkTurquoise
darkWood
dimGray
dimGrey
dkGreenCopper
dustyRose
feldspar
firebrick
flesh
forestGreen
gold
goldenrod
gray05
gray10
gray15
gray20
gray25
gray30
gray35
gray40
gray45
gray50
gray55
gray60
gray65
gray70
gray75
gray80
gray85
gray90
gray95
gray
green
greenCopper
greenYellow
grey05
grey10
grey15
grey20
grey25
grey30
grey35
grey40
grey45
grey50
grey55
grey60
grey65
grey70
grey75
grey80
grey85
grey90
grey95
grey
huntersGreen
indianRed
khaki
lightBlue
lightGray
lightGrey
lightPurple
lightSteelBlue
lightWood
limeGreen
magenta
mandarinOrange
maroon
mediumAquamarine
mediumBlue
mediumForestGreen
mediumGoldenrod
mediumOrchid
mediumSeaGreen
mediumSlateBlue
mediumSpringGreen
mediumTurquoise
mediumVioletRed
mediumWood
medPurple
mica
midnightBlue
navy
navyBlue
neonBlue
neonPink
newMidnightBlue
newTan
oldGold
orange
orangeRed
orchid
paleGreen
pink
plum
quartz
red
richBlue
salmon
scarlet
seaGreen
semiSweetChoc
sienna
silver
skyBlue
slateBlue
spicyPink
springGreen
steelBlue
summerSky
tan
thistle
turquoise
veryDarkBrown
veryLightPurple
violet
violetRed
vLightGray
vLightGrey
wheat
white
yellow
yellowGreen

easingFuncs

The easingFuncs library makes Robert Penner's easing functions available for use in animations.

var easing = cpov.requireOptLib("easingFuncs");

The following diagram illustrates the speed-over-time curves of the easing functions:

Methods

All of the easing functions take the same four arguments: currentTime, startVal, change, and duration. (A few of them take an optional fifth argument, s, which is a tuning value.) The currentTime argument specifies the current time in whatever unit you're using, e.g., frames, seconds, etc., while duration specifies the total length of the easing sequence. The initial value of the property being eased is startVal, and change is the amount by which that value changes over the course of the animation.

For example, if you want to animate some object's x value from 0 to 50 over the course of thirty frames using easeInBounce, you might try something like this:

var easing = cpov.requireOptLib("easingFuncs"); for(var frame = 0; frame < 30; frame++) { obj.center.x = easing.easeInBounce(frame, 0, 50, 30); obj.snapshot(); cpov.outputFrame(); }
easeInBack(currentTime, startVal, change, duration, s)
easeInBounce(currentTime, startVal, change, duration)
easeInCirc(currentTime, startVal, change, duration)
easeInCubic(currentTime, startVal, change, duration)
easeInElastic(currentTime, startVal, change, duration)
easeInExpo(currentTime, startVal, change, duration)
easeInOutBack(currentTime, startVal, change, duration, s)
easeInOutBounce(currentTime, startVal, change, duration)
easeInOutCirc(currentTime, startVal, change, duration)
easeInOutCubic(currentTime, startVal, change, duration)
easeInOutElastic(currentTime, startVal, change, duration)
easeInOutExpo(currentTime, startVal, change, duration)
easeInOutQuad(currentTime, startVal, change, duration)
easeInOutQuart(currentTime, startVal, change, duration)
easeInOutQuint(currentTime, startVal, change, duration)
easeInOutSine(currentTime, startVal, change, duration)
easeInQuad(currentTime, startVal, change, duration)
easeInQuart(currentTime, startVal, change, duration)
easeInQuint(currentTime, startVal, change, duration)
easeInSine(currentTime, startVal, change, duration)
easeOutBack(currentTime, startVal, change, duration, s)
easeOutBounce(currentTime, startVal, change, duration)
easeOutCirc(currentTime, startVal, change, duration)
easeOutCubic(currentTime, startVal, change, duration)
easeOutElastic(currentTime, startVal, change, duration)
easeOutExpo(currentTime, startVal, change, duration)
easeOutQuad(currentTime, startVal, change, duration)
easeOutQuart(currentTime, startVal, change, duration)
easeOutQuint(currentTime, startVal, change, duration)
easeOutSine(currentTime, startVal, change, duration)

Internals: Hacking CephaloPOV

This section, it will surprise absolutely no one, started as a simple reference to help me get through the first version and be able to tolerate the fairly frequent and sometimes lengthy interruptions during which code you wrote with your own hands becomes someone else's code. The same information serves well as a guide for other developers, so I'm making an effort to keep it up to date and flesh it out. That said, you know how far I am from completing the end-user docs? I am even further away from finishing the developer docs.

In the meantime, feel free to ask questions on the development mailing list, and if you feel like adding to the documentation (hint, hint) then just submit a pull request.










Platform Details

CephaloPOV is developed and tested using something close to the latest LTS release of Node. As of 2021-08-08, this is version 14.17.4. I am making no commitment to maintain compatibility with older versions of Node, but if you encounter a regression with different versions of Node, I will be happy to see if there's a way to fix it without being bound to something other than the latest Node version. I will be even happier if you figure it out and submit a patch.

For various practical reasons, my personal development machine is relatively recent desktop machine running Windows 10 along with Cygwin. The main CephaloPOV program is tested running from the Windows command prompt, as well as Cygwin's version of bash and whatever reasonably current Linux distribution I happen to have handy at the time. If you're going to work on CephaloPOV, you probably want to do it under Linux or Windows+Cygwin, as the build and test scripts are neither tested nor maintained for the Windows shell. As with the main program, I am happy to look into platform compatibility issues, but grinding out MS-DOS .bat files to maintain parity with the corresponding bash scripts is not going to be a high priority for me.

In general, I am trying very hard to avoid doing anything that would require platform-specific code, mainly because I don't want to be responsible for maintaining a port to platforms I do not have ready access to. I am not opposed to someone contributing platform-specific features, but only if the contributors are willing to maintain their contributions.

The File Manifest

Only the important files are listed here. Things like individual graphics files for the documentation and generic infrastructure like package.json are omitted.

/build.js .............. Generates classes.js and parts of the documentation. /cpov.js ............... Contains the main loop, mostly because typing "cpov" is quicker than typing "cephalopov". /illus.js .............. CephaloPOV program for generating illustrations for the docs. /docs/index.html ....... The main documentation file, parts of which are updated from the *Def.js files by build.js. /docs/src .............. The POV-Ray files generated by illus.js end up here. /lib/cephalopov.js ..... Contains the main program logic. /lib/classes.js ........ All of the JS classes used by CephaloPOV; generated by build.js. /lib/colorsInc.js ...... Color definitions converted from POV-Ray's colors.inc. /lib/easingInc.js ...... Optional easing functions. /lib/file.js ........... (Extremely) simple file i/o object. /lib/gsDef.js .......... Definition of the GlobalSettings class; used by build.js. /lib/ioDef.js .......... Definition of the ImageOptions class; used by build.js. /lib/manual.js ......... Non-generated classes. /lib/minicle.js ........ CLI argument parser and terminal I/O. /lib/objDef.js ......... Definitions for JS classes wrapping POV-Ray graphics primitives; used by build.js. /lib/primitiveDef.js ... Definition of the Primitive class; used by build.js. /lib/snippets.js ....... Manually produced code for inclusion in classes.js. /lib/textureDef.js ..... Definitions of Texture and related classes; used by build.js. /lib/vectorDef.js ...... Definitions of Vector* and Color classes; used by build.js. /LICENSE ............... All your base are belong to, well, all of us. /README.md ............. Generic README for GitHub and NPMjs /tests/* ............... Various test scripts

The Build Process

The build process for CephaloPOV is a bit eccentric. It arose during the process of settling on the current architecture, which was the fourth attempt at doing so. I was determined to get it right and not settle on a sub-optimal solution simply because of the effort that went into building it or the effort that would be required to replace it with something else.

Consequently, it is a data-driven code generation process. Classes are defined in a number of definition files, e.g., objDef.js, PrimitiveDef.js, etc., and this drives the creation of the main code file, classes.js and parts of the documentation. Earlier versions were purely declarative, but that resulted in an apparently endless process of coding exceptions and edge cases, so the current version uses automatic code generation where it is convenient and clear, but it grabs named blocks of manual code from snippets.js where that is easier.

It should be noted that both the definition files and their processor, build.js, may be eliminated once CephaloPOV is complete and has been stable for a while. Persons who want to fork CephaloPOV and go in their own direction might want to at least consider doing away with it now, but for the time being, modifying the program means dealing with the code generation system, so it is documented here.

build.js

As noted above, build.js manages the build process. It's an ordinary command line JavaScript program that you will find in CephaloPOV's root directory. Pass it the -h switch for usage instructions:

$ node build.js -h Usage: build [options] -c, --classes Generate classes.js -d, --docs Update autogen text in index.html -s, --snippets Regenerate snippets.js --> snippets.new.js -o, --objlist Produce list of object classes -h, --help Display this text

The first two options, --classes and --docs, are the only essential ones. The --classes switch will rebuild classes.js by reading from the various *Def.js files and snippets.js. In so doing, classes.js is overwritten and replaced. The --docs switch rebuilds parts of the documentation in docs/index.html by replacing the HTML in specially marked sections (see the docHumper function for more details). Text outside of those sections is left unaltered.

The other two options, --snippets and --objlist, are convenience tools. The --snippets switch just reads snippets.js and writes it back out to snippets.new.js with a little bit of formatting cleanup. The --objlist switch simply outputs a list of generated classes, which of course excludes classes that are entirely manually defined, such as Matrix.

It's only fair to warn you that while build.js is not a large program, parts of it are pretty hairy, so tread with caution if you want to modify it.

The *Def.js Definition Files

Each of the definition files consists of a JavaScript object or objects defining the parameters of a generated class and specifying the names of chunks from snippets.js to fill in specialized functionality. The format of the definition objects is pretty simple and not at all hard to figure out even without documentation, but we'll walk through a (hypothetical) object that exercises all of the features at once.

At the top level of each object are some or all of the following members:

something: { superclass: "Primitive", desc: "The something class implements some geometric primitive.", conArgs: false, conBlock: false, snippets: ["Cylinder.toSDL"], immutable: { finite: true, solid: true, csg: false, csgOperand: false }, mutable: [ ... ] }

The superclass member defines the parent class, if any. For base classes, this can be omitted. The desc member holds a human-readable description of the class for the docs. (This isn't actually in use yet, but it eventually will be. In the meantime, it's okay to leave it false.)

If you look through the generated code in classes.js, you'll notice that almost all of the constructor methods take a single argument, options. This is the default produced when conArgs is false. Should you wish to override this behavior, conArgs can be set to a string which will be placed in the constructor signature.

The conBlock member can be a string containing the name of a snippet to insert into the constructor method after the declaration of the mutable members (for which, see below). It is usually false.

The snippets member is either false or it is an array of strings containing the names of snippets to include in the class. They are inserted after the generated methods in the order given.

As noted in the user documentation, all primitive types have a set of immutable (i.e., read-only) attributes. These are specified as an object whose keys are the desired attribute names and values. These are converted into accessor functions during code generation.

The final and largest part of the class definition appears in the mutable member, which defines the mutable attributes of the class and/or specifies a snippet to handle them. They look something like this:

mutable: [ { name: "location", req: true, valid: "cpov.isClassInstance(val, 'VectorXYZ') || (val = cpov.convertToVector('VectorXYZ', val))", err: "location must be a VectorXYZ.", desc: "Specifies the location of the light source.", tname: "VectorXYZ" }, // ...

The name member corresponds to the name of the accessor methods. Their internal representations are stored with an underscore prefix, e.g., _name, because JavaScript doesn't yet support actual private object members. These are largely initialized to null in the constructor. The req member is a boolean which determines whether or not the member must be initialized prior to being output as SDL code.

Validation at assignment time is performed by the code snippet in valid, which on failure outputs the error message defined in err. The description of the member in the documentation is provided by desc, and the contents of tname are used in the docs to specify the type of the class member.

There are a few additional members that are not shown in the example above. In a few cases, the autogenerated accessor methods are inadequate, so custom specifies the name of a snippet to use instead. For mutable members that are managed by CephaloPOV, like the parent members of objects contained by other objects, setting dperm to "RO" will make them read-only to user programs. Attributes containing other objects will also have a child member with a value of either "scalar" or "array", which tells CephaloPOV that those objects' parent attributes must be updated upon assignment.

snippets.js

Everything sufficiently complex or specialized that it is easier to code manually than to generate lives in snippets.js. The organization of the file is extremely simple. Each code block begins with a specially formatted comment to define its name, and the associated code continues until the next special comment or the end of the file, whichever comes first. The special comments look like this:

// SomeArbitraryName //---------------------------------------------------------

The comment must begin in the first column, and the spaces between the slashes and the name are required. The name itself cannot contain spaces. Everything following the trailing slashes is ignored; the dashed line is just for easy readability.

And that's it for snippets.js: it's just a collection of named chunks of code which are inserted in the generated classes as directed by the snippets member of the class definitions in the *Def.js files.

In case you're wondering about motivations, you should know that the first version attempted to automate nearly everything, but then I ended up spending more and more time maintaining and extending a version of build.js that was increasingly resembling a compiler. The current version mostly handles the tedious boilerplate involved in wrapping POV-Ray's collection of primitives into JavaScript classes, making it easy to update and debug those portions. Everything else ends up in snippets.js, including the occasional entire class definition, as with Matrix.

Inside the cpov Object

Nearly everything other than class definitions and user code lives in the global cpov object, a singleton which is initialized in cephalopov.js.

Data

TODO

Methods

Because most of the code in CephaloPOV lives in classes, the cpov object's methods consist mainly of small generic data validation, data conversion, and odd utility functions. The validation and conversion methods are particularly important because they are used throughout the various classes to implement CephaloPOV's type system, so it is worth taking the time to familiarize yourself with them.

cpov.arrayToTextList(items)

Used in error messages and the auto-generated parts of the documentation, this function takes an array of strings and returns a string in which they are delimited by commas and the conjunction "or". For example, ["one", "two", "three"] becomes "one, two, or three".

cpov.convertToVector(type, val)

Setter methods in CephaloPOV objects that accept types VectorXY, VectorUV, VectorXYZ, VectorXYZW, or Color will also accept bare arrays just like the constructors for those classes. This is not coincidentally accomplished by passing val to the constructor for type and returning the result. Validation of val is left to the class' constructor and setter methods.

cpov.convertToVectorArray(type, val)

This is just the array version of cpov.convertToVector, where val is an array of numeric arrays instead of a single array. Returns the an array of objects of the specified type.

cpov.deg2rad(deg)

Converts the value of deg from degrees to radians and returns the result.

cpov.endAnimation()

When called by the user program, this method terminates the animation loop. If a frame is in progress when it is called, it will not be output, so it is normally called after file output.

cpov.error(level, message, location = "CEPHALOPOV", obj = null)

Outputs an error message using pretty colors if supported by the terminal. The level argument may be one of "fatal", "warn", "info", or "debug". If level is "fatal", the program terminates immediately unless cpov.settings.debug is greater than 1. (This is useful for debugging when working on CephaloPOV itself.) All other error levels simply emit an error message. This will appear on the terminal for "warn", "info", and "debug" at cpov.verbosity levels of 1, 2, and 3, respectively. In all cases, the error will also be written to cpov.settings.debugLog if initialized.

The error message is prefixed with the location where the error occurred, usually a class and method name, and the object serial and id, if any, are appended to the end of the line.

cpov.indentTextBlock(block, stops)

Takes a block of text in the form of a single string with embedded newlines and prefaces each line with the specified number of tab stops, returning the result. This function is heavily used in code generation.

cpov.inheritsFrom(val, classname)

Returns a boolean indicating whether object val is an instance of classname.

cpov.initObject(obj, vals)

Standard initialization routine for most objects. Attempts to assign the values in vals, a simple JavaScript Object to the CephaloPOV object obj. Attributes that do not exist in obj will be ignored, and the setter methods of obj may throw a fatal error if the values fail whatever validation is applied to them. This routine is used for objects without an explicitly defined conBlock.

cpov.isArrayOfBaseClass(val, classname, min, max)

Returns true if val is an array of objects of any class inheriting from base class classname with min to max elements, false otherwise.

cpov.isArrayOfClass(val, classname, min, max)

Returns true if val is an array of objects of class classname with min to max elements, false otherwise.

cpov.isArrayOfFloats(val, min, max)

Returns true if val is an array of floats (i.e., type Number) with min to max elements, false otherwise.

cpov.isArrayOfInts(val, min, max)

Returns true if val is an array of integers with min to max elements, false otherwise. See cpov.isInt for what constitutes an integer in JavaScript's int-less type system.

cpov.isArrayOfNonEmptyStrings(val, min, max)

Returns true if val is an array of non-empty Strings with min to max elements, false otherwise.

cpov.isArrayOfStrings(val, min, max)

Returns true if val is an array of Strings with min to max elements, false otherwise.

cpov.isArrayOfSubclass(val, classname)

Returns true if val is a member of a class inheriting from classname, false otherwise.

cpov.isBetween(val, min, max)

Returns true if min < val > max, false otherwise. See also cpov.isWithin.

cpov.isBoolean(val)

Returns true if val is of type boolean, false otherwise. Note that it is the type of val that is being tested for, not its literal boolean value.

cpov.isChar(val)

Returns true if val is of type String with a length of 1, false otherwise. JavaScript of course does not have a char type; we're just emulating one for POV-Ray's sake using single-character strings.

cpov.isClassInstance(val, classname)

Returns true if val is a member of class classname, false otherwise.

cpov.isFloat(val)

Returns a boolean indicating whether val is a Number. It is so named because POV-Ray makes a distinction between floats and ints, and hopefully JavaScript will eventually be able to make the same distinction.

cpov.isFunction(val)

Returns a boolean indicating whether val is either a JavaScript function or an SDL function.

cpov.isInArray(val, array)

Returns true if val appears as an element of array, false otherwise.

cpov.isInt(val)

Returns true if val is an integer, which for the purposes of JavaScript's lack of true integers means that the type of val is Number and it has no fractional part. Returns false otherwise.

cpov.isJSFunction(val)

Returns true if val is a JavaScript function, false otherwise.

cpov.isKey(val, object)

Returns true if object[val] is defined, false otherwise.

cpov.isNonEmptyString(val)

Returns true if val is of type String and has a non-zero length, false otherwise.

cpov.isNull(val)

Returns true if val is null, false otherwise.

cpov.isNullOrFunction(val)

Returns true if val is null, an object of type Function, or an SDL function, i.e., a string beginning with "&". In all other cases, it returns false.

cpov.isNullOrJSFunction(val)

Returns true if val is null or an object of type Function. In all other cases, including SDL function strings, it returns false.

cpov.isPowerOfTwo(val)

Returns true if val is a power of two, false otherwise. As implemented, it only operates in the interval 20–264.

cpov.isSDLFunction(val)

Returns true if val is an SDL function, which for the purposes of CephaloPOV is a String beginning with an ampersand, i.e., "&".

cpov.isString(val)

Returns true if val is of type String, false otherwise.

cpov.isUnusedId(val, obj)

CephaloPOV objects may contain a user-supplied GUID. This function tests whether val is already in use with another object. If not, it adds obj to cpov.idMap with val as an index and returns true. If val is already in use, it returns false instead.

cpov.isUnusedSerial(val, obj)

In addition to optional user-supplied GUIDs (see cpov.isUnusedId, above), every CephaloPOV object has a unique serial number. This function tests whether val is already in use with another object. If not, it adds obj to cpov.serialMap with val as an index and returns true. If val is already in use, it returns false instead.

cpov.isValidPatternType(val)

Takes a pattern name and returns a boolean indicating whether it is supported.

cpov.isWithin(val, min, max)

Returns true if minvalmax, false otherwise. See also cpov.isBetween.

cpov.keysToTextList(obj)

This function converts the keys of obj to an array and wraps each element in single quotes before passing it to cpov.arrayToTextList to convert it into a comma-delimited string for use in the auto-generated parts of the documentation.

cpov.objectImport(filename)

Takes a filename, which is currently always snippets.js, and parses it using specially formatted comments of the form

// Keyname //-------------------------------------------------------------------

where the initial slash appears in the first column. The keyname is extracted and used to index the following text up to the next special comment. Although the examples you will see in snippets.js all have a line of trailing dashes, everything past the last slash is ignored. The spaces on either side of the keyname are mandatory, and the name itself cannot contain any whitespace.

The resulting object is returned and used for inserting the named blocks of code into the generated code, mostly in classes.js.

cpov.outputFrame()

The cpov.outputFrame method exists for user programs to call whenever they have finished setting up a scene. It takes no arguments, its behavior being determined mostly by cpov.imageOptions and cpov.globalSettings. That behavior is already described in great detail in The Animation Cycles and will not be repeated here.

There is no return value. If any termination conditions are met, CephaloPOV will terminate with an exit code of 0.

cpov.primitiveDefIdentifier(obj)

Given a CephaloPOV object, returns a unique string consisting of the form #serial:id. If the object does not have an id, both it and the interstitial colon are omitted. This is appended to the error messages emitted by cpov.error.

cpov.requireOptLib(alias)

CephaloPOV includes a number of optional libraries that are not automatically loaded at runtime. Each is identified by a mnemonic alias passed to cpov.requireOptLib, which in turn loads the library and returns it to the caller. Many of these are ports of POV-Ray include files to JavaScript identified by their original filename, e.g., colors.inc.

cpov.round(n, d)

Takes a number, n, and returns it rounded to d decimal places.

cpov.runAnimation()

This is the main animation loop which repeats, calling cpov.outputFrame() repeatedly until one of its termination conditions are met or the user program calls cpov.endAnimation.

cpov.tab(stops)

One of the functions used in formatting generated code, both JavaScript and SDL, returns a string containing 4 * stops spaces. Do not submit a pull request changing this to tabs or other numbers of spaces, or I will curse you and your progeny.

cpov.testStage(type, size)

Returns an array of objects that serve as stages or backdrops for geometric objects generated for tests and illustrations in the CephaloPOV documentation.

If type is given as "corner", the generated stage consists of three adjacent faces of a cube around one corner in the same configuration as a corner reflector. The faces are size units square and the axes run through the centroids of each face. If type is "triplane", then the stage takes the form of three translucent planes intersecting at the origin.

Cameras and lighting are included in the stage. It is assumed that the final image will have a 1:1 aspect ratio, so you will have to adjust the camera parameters, particularly camera.right, if you want a different aspect ratio.

It is highly likely that this function will be extended and changed in backwards-incompatible ways to serve the needs of documentation and testing, so if you want to use it outside of CephaloPOV itself, it's best to make your own copy of the function.

cpov.timerStats(start, end, units = 1)

This function is used to calculate performance statistics. It takes a start and end time and a number of work units, and it returns an object containing the elapsed time in milliseconds and seconds and the average times per unit. (The units are usually frames.)

cpov.yieldAttribute(attr, obj, allowSDL)

This function is used in the code generation process for classes.js and handles returning the value of an object appropriately depending on whether the value is a JavaScript function, an SDL snippet, or a general value.

Appendices

The appendices contain further details and discussions about CephaloPOV and ray tracing supplementary to the main text.










Matrices

SDL matrices are an abbreviated form of the entire matrix being used. The fourth column is invariant and therefore omitted from its SDL representation and inaccessible within CephaloPOV, but we show it below in grey for the math-curious. You don't have to know much about matrix math to use the Matrix class. Like SDL, CephaloPOV offers shortcuts to the individual transformations in the form of special arguments to the Matrix constructor and the apply method.

Translation, Scaling, and Skewing

Red elements determine scaling, blue elements determine translation, and green elements determine skewing. (The grey elements, as previously mentioned, are invariant and hidden in both POV-Ray and CephaloPOV.) Note that there are three elements for each axis when scaling and translating, but there are six elements for skewing, because skew transformations involve relationships between pairs of axes.

Column
0
Column
1
Column
2
Column
3
Row
0
v00
Scale X
v01
Skew Y by X
v02
Skew Z by X
(v03)
0
Row
1
v10
Skew X by Y
v11
Scale Y
v12
Skew Z by Y
(v13)
0
Row
2
v20
Skew X by Z
v21
Skew Y by Z
v22
Scale Z
(v23)
0
Row
3
v30
Translate X
v31
Translate Y
v32
Translate Z
(v33)
1

An important thing to notice here is that while the matrix elements that determine translation and skewing are 0 if no translation or skewing is to be done, the elements that define scaling must be 1 when no scaling is to be done, i.e., it's an identity element. Setting the scaling elements to zero will make the object disappear!

Another thing to notice about scaling is that negative values will reflect the object across the relevant axis. In the special case of 1, this will be a perfect mirror image; other values will stretch or squash the object.

Rotation

Rotation is a little more complicated because it requires the use of trigonometric functions. This is handled for you by the Matrix class' rotate constructor argument, but it's worth understanding in case you want to try doing the calculations yourself or trying variations to see what they do.

Since the values for rotations around the axes overlap, we'll omit the invariant fourth column and the translation row so we can cram all three rotation matrices into a single row. In this case, we'll color the rotation elements red, the single scale identity element blue, and everything else grey. If you're entirely innocent of trigonometry, know that cos and sin are the trigonometric functions cosine and sine, which are implemented in JavaScript as the Math.cos() and Math.sin() methods. The angle of rotation is conventionally represented by the Greek letter theta, θ, and is specified in radians, though POV-Ray and CephaloPOV expect you to use degrees instead and quietly translate degrees into radians for you.

Rotation around the X axis
Col.
0
Col.
1
Col.
2
Row
0
v00
1
v01
0
v02
0
Row
1
v10
0
v11
cos(θ)
v12
sin(θ)
Row
2
v20
0
v21
-sin(θ)
v22
cos(θ)
Rotation around the Y axis
Col.
0
Col.
1
Col.
2
Row
0
v00
cos(θ)
v01
0
v02
-sin(θ)
Row
1
v10
0
v11
1
v12
0
Row
2
v20
sin(θ)
v21
0
v22
cos(θ)
Rotation around the Z axis
Col.
0
Col.
1
Col.
2
Row
0
v00
cos(θ)
v01
sin(θ)
v02
0
Row
1
v10
-sin(θ)
v11
cos(θ)
v12
0
Row
2
v20
0
v21
0
v22
1

Note the sign of the sine functions. These are specific to the left-handed coordinate system that POV-Ray uses. In a right-handed system, you'd reverse the signs.

If you want to know more, Jeff Lee's POV-Ray-specific tutorial is a good place to start, as are these course notes. To dig deeper than that—and there's a lot more you can do with matrices—the topic is covered in depth in 3D graphics and linear algebra textbooks. And don't be scared off: it's far more tedious than difficult. Choose a simple shape, try fiddling with different elements and different functions, and look at the results of a rendering.

Credits and Licenses

Every effort has been made to credit everyone whose code I used either directly, with modifications, or even as a model. I have also tried to credit everyone who provided technical instruction. If I missed anyone, please speak up.

The first round of applause goes to David K. Buck and all of the many subsequent developers who have built, maintained, and extended POV-Ray for the last three decades. A second round of applause goes to the folks who wrote POV-Ray's extensive documentation. Special thanks are also in order to Eric Haines, whose Ray-Tracing News kindled my interest in the field back when I was reading copies via gopher on a 3270 terminal at the University of Florida.

CephaloPOV itself is licensed under the BSD 2-clause license, which appears at the head of most of the files in the sources. For the npm dependencies, see package.json.

The easing equations used for animations originate with Robert Penner, who released them under the BSD 3-clause license. They were implemented in JavaScript for jQuery by George McGinley Smith, who subsequently released his code under the same license. It was from there that they were adapted (mostly by renaming variables and reformatting) for CephaloPOV.

Administrivia

TODO

Version 0.0.4
Status Type Pri Description
pendingI+TC★Modify build process to allow suppression of the default copy method.
pendingI+TC★Remove id and declare from Primitive.copy and Primitive.copyFrom.
pendingI+TC★Finish Finish: snippets, docs, tests.
pendingI+TC★Lemon: new Primitive.
pendingI+TC★Survey 3.7.1 new features for backpatching.
pendingI+TC★LightSource: Implement restrictions for area lights generally and the orient keyword in particular.
pendingI+TC2LightSource.looksLike
pendingI+TC3LightSource.projectedThrough
pendingI+TD★LightSource description and examples
pendingI+Tc Separate repo for tests/examples and a lot of stuff to go into it before the next version.
  • Blob disc
  • Pyramids...
  • Parametric building
  • Stereogram
  • Equirectangular scene(s)
  • Heightfield oceanside scene
  • Navigable 360 pano building
  • Cruiser design
Version 0.0.5
   
Status Type Pri Description
pendingI+T Mesh2 description and example
pendingI+T Compact output format for Triangles in Mesh
pendingI+T Mesh/Triangle: Improve constructor validation
pendingI+T uvVectors member in Triangle, check Mesh compatibility.
pendingI+T Mesh2
pendingI+T Mesh description and example
pendingDOCD8Document the various spline types.
pendingI+T Make sure Primitive.destroy recurses through child objects.
pendingI+T Validate Polynomial.order.
pendingI+T copy() method across classes, both shallow and deep
pendingI+T cpov.js: More selective scope management, untangle internal dependencies
pendingI+T Management of array attributes
pendingI+T Execution: Oversee execution directly
workingI+T Texture subsystem
workingI+TNormal and NormalMap
workingI+TPigment and PigmentMap
workingI+TTexture and TextureMap
pendingI+T Primitive
pendingI+T Primitive.interior
pendingI+T Primitive.interiorTexture
pendingI+T Primitive.photons
pendingI+T Primitive.radiosity
pendingI+T Primitive.texture
pendingI+T Atmospheric effects
pendingI+T Reports
pendingI+T Illustration stage generator: translucent XYZ planes, n x n, adjust camera
pendingI+T LightSource.mediaAttenuation
pendingI+T LightSource.mediaInteraction
pendingIMPcCamera.normal
Backlog
Status Type Pri Description
TBDTBDTBDA large set of sample functions/variants for the IsoSurface type and the polynomials.
TBDTBDTBDAdditional splines, esp. Catmull-Rom, and interface with easing functions
TBDTBDTBDAngles in the unit interval
TBDTBDTBDAutomatic normal calculations, etc., for Triangle and Mesh/Mesh2 Maybe native code or an external util.
TBDTBDTBDColor and texture SDL generation, i.e., in separate file to use directly with POV-Ray
TBDTBDTBDDirect support for ffmpeg/avisynth + Google speech API
TBDTBDTBDDrag in some color libraries, theme generators
TBDTBDTBDEric Haines' table of object intersections, collision detection
TBDTDBTBDExternal batch rendering util.
TBDTBDTBDFix inputFileName and outputFileName in ImageOptions if needed.
TBDTBDTBDGeometric query system
TBDTBDTBDhttps://www.npmjs.com/package/ml-matrix (?)
TBDTBDTBDLevel-of-Detail
TBDTBDTBDMacro/Function generation, i.e., in separate file to use directly with POV-Ray
TBDTBDTBDObject serialization and packages.
TBDTBDTBDParametric compound types, i.e., not the Parametric primitive.
TBDTBDTBDParticle systems
TBDTBDTBDPolyhedron library
TBDTBDTBDPorting of functions/presets in .inc files
TBDTBDTBDScript execution on events
TBDTBDTBDScript to parse as much as possible of POV-Ray .inc files into JS/cpov
TBDTBDTBDSpecify a config file from the command line.
TBDTBDTBDSpline-builder UI
TBDTBDTBDStereo pseudo-cameras
TBDTBDTBDReorg: Script to pretty-print definition files
TBDTBDTBDWrap Array attributes with Proxies to enforce type (?)
TBDTBDTBDTurtle graphics -- snapshot mode forms part of the basis for this.
TBDTBDTBDUTIL: ffmpeg-based animation generator
TBDTBDTBDUTIL: Google speech api text-to-wav
TBDTBDTBDUTIL: Render script

CephaloPOV Scene Graph

Master objects are defined relative to the origin. More precisely, the origin is their primary point of articulation. In each frame, they are transformed to their current frame-state.

Possibly, a relationship between A and B is stated in the form of B's point of articulation relative to some explicit or implicit point in A. In its most basic form, this would amount to free movement of B relative to its attachment point to A. PSII could provide a set of standard constraints, e.g., ball joint, hinge, track, etc., which could be built upon or supplanted by the user.

This suggests a separate assembly process for objects with moving parts, which means that ordinary native CSG objects can go ahead just fine. Converting them into master objects amounts to just positioning them appropriately relative to the origin after construction.

Changelog

Oh geez, not yet.