2013.10.10

sc3.rasterization.scanfill

Added a quick, first-pass implementation of a triangle scanfill algorithm. (I'm sure it needs tweaking for corner cases and pixel center issues).

The live example is here.

2013.10.10

Inspecting the assembly of V8 on Windows

Being able to see the x86 assembly code that V8 generates from Javascript can be quite insightful. This post is basically just build instructions for the stackoverflow post describing how to view the disassembly

Building V8 on Windows

(Yes, this information is elsewhere, but I wanted to provide this as one specific example of what worked for me as the general build guide can be confusing as it is not a one-step process and the docs try to cover all platforms.)

These build steps assume, you have:

  • Python 2.7 installed
  • Git Bash installed
  • Microsoft Visual Studio 1.0

To get started, open a git-bash shell and pull all the dependencies. We use git-bash here as it has access to both git and svn.

$ git clone git://github.com/v8/v8.git v8 && cd v8

$ svn co http://gyp.googlecode.com/svn/trunk build/gyp
...
 $ svn co https://src.chromium.org/chrome/trunk/deps/third_party/icu46 third_party/icu
...
$ svn co http://src.chromium.org/svn/trunk/tools/third_party/python_26@89111 third_party/python_26
...
$ svn co http://src.chromium.org/svn/trunk/deps/third_party/cygwin@66844 third_party/cygwin

Open a Windows command prompt to do the build. We're building with a couple non-default flags per this stackoverflow post.

> set PATH=%PATH%;c:\Python27
> "c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2010 x86 tools.

> python build\gyp_v8 -Dv8_enable_disassembler=1 -Dv8_object_print=1

Updating projects from gyp files...

> devenv.com /build Release build\All.sln

Open build/all.sln, switch to Release and build. (This is possible to do from the command-line as well.)

Running the resulting build

Create a file hello.js with the content print("hello world");.

> build\Release\shell.exe --print_code hello.js

It should print out the disassembly for the file to stdout.

2013.10.07

Added Patterns

Added a few basic pattern generators to surfacecurve-gfx:

Not very exciting at the moment, but the eventual goal is to support a larger set of patterns and integrate them into the shader builder.

2013.10.05

WebGL Nested Procedurals

Added support to surfacecurve-gfx library for generating nested procedruals.

Here's a link to the live example.

The example shows a solid colored shader, a checker shader, and a nested checker shader. The shader source is generate from a JSON shader graph specification - not hand-coded shaders. The surfacecurve-shaderbuilder package handles the shader generation.

Nested Checker specification

{
    diffuse : {
        color : { 
            checker : {
                uv     : { spherical : { scale : [4, 4] } },
                color0 : {
                    checker : {
                        uv     : { spherical : { scale : [8, 8] } },
                        color0 : {
                            checker : {
                                uv     : { spherical : { scale : [32, 32] } },
                                color0 : [ 0.7, 0.7, 0.7 ],
                                color1 : [ .85, .85, .85 ]
                            }
                        },
                        color1 : [ 0.95, 0.95, 0.98 ]
                    }
                },
                color1 : {
                    checker : {
                        uv     : { spherical : { scale : [16, 16] } },
                        color0 : [ 0.8, 0.8, 0.8 ],
                        color1 : {
                            checker : {
                                uv     : { spherical : { scale : [32, 32] } },
                                color0 : [ 0.1, 0.1, 0.1 ],
                                color1 : [ .9, .9, .9 ]
                            }
                        }
                    }
                }
            }
        }
    }
}
(Yup, the nested procedural is deeply nested.)

2013.09.30

surfacecurve-gfx update

The surfacecurve-gfx library (very early development) now supports a basic unit_circle primitive...

Here's a link to the example.

...

Geometry buffer sharing and level-of-detail support are two unsupported features that immediately jump to mind as "needed" but, one piece at a time. For example, basic line and point rendering are higher priority than optimizing the 2D circle rendering pipeline.

2013.09.20

Improving NPM

I'm a fan of the Node Package Manager (NPM). It provides a well-engineered solution to the contentious problem of software dependencies. It works well with Node.js projects and I've used it with pure C/C++ projects as well. As with most things often used and enjoyed, it's hard not to consider how to further improve NPM...

Prefix names by user name

Example: if I want the "moment" package, I should have to prefix it by one of the maintainer's names:

"timrwood/moment"    : 2.2.1,

Why?

  • This more elegantly allows for transfer of ownership - as there is not transfer. (I.e. package user X stops maintaining the popular package and user Y creates a useful, improved fork.)
  • It's more "equal opportunity" namespacing. If I want to call my Nonfinite-Precision Mathematics library "npm", I can...
2013.09.18

Computing a file SHA-1s in Node

TL;DR

function computeSHA1(filename, done)
{
    var hash = require("crypto").createHash('sha1');

    var stream = fs.createReadStream(filename);
    stream.on("data", function (chunk) {
        hash.update(chunk);
    });
    stream.on("close", function() {
        var sha1 = hash.digest();                    
        done(null, sha1);
    });
}
2013.09.18

Unsolved nodemon memory leak

I frequently use nodemon to make developing with node more efficient. I recently noticed that memory usage is increasing at about 1K / 5 seconds when running this site. The problem does not occur when launching the site with vanilla node. I'm using nodemon v0.7.10. For now, the solution is to use vanilla node...

Instances

This document is a work-in-progress

A collection of notes on the Instance class.

A "world" in surfacecurve is, by and large, composed of a set of Instance objects. (These in turn can be generated by Entity objects, or composed of shared Geometry objects and other sub-objects -- but that can be ignored for now.)

Selector model

The engine supports DOM/CSS-like selector model. As such each instance has:

  • id
  • class list

The id is intended to be a unique name that, if it has an semantic meaning, is application-specific.

The class list is a set of names. Likewise, these names have no overt semantic meaning to the Engine and can be used by the application as a grouping and property sharing mechanism. The class attribute will eventually support overlays of shared properties -- but this is a future feature.

Properties

TBD.

An Instance is primarily a data object, not a functional object.

A property is a top-level, semi-standardized (by convention) named value such as position or color.

Components

A component is an optional sub-object of the Instance object. For example instance.physics might define the physical properties of the instance for use by both the physics subsystem and, in some cases, the graphics subsystem.

Caches

TBD.

Subsystem can also attach cached data.

Interactions between subsystems

As an test case for the engine architecture, I want to do the following:

  1. Create a curved surface roughly parallel to the XY plane
  2. Create N random spheres above the plane over a period of M seconds
  3. Compute the trajectory of each sphere based on the physics of applying gravity to each sphere
  4. Draw the entities as "ghost" entites (opacity < 1, no physics interaction) along with lines representing their trajectories
  5. Animate the "real" entities according to the physics

Generalization

Generalizing this...

  1. Create a fixed world of instances
  2. Add an entity that generates N new instances in the scene
  3. Add a plug-in that for some subset of instances computes a trajectory for them and adds the ghost elements
  4. Add

With the following considerations:

  • The instances need some selectors or grouping
  • The instances need some properties specific to subsystems (e.g. mass, "bounciness")
  • The engine needs the notion of instances that do or do not participate in a subsystem's logic

Collision Trace

Pseudo-code:

engine.on('add').filter(".tracephysics").callback(function() {
    var physics = engine.subsystem.physics;
    var path = physics.trace(this);

    var set = pathToInstances(path).addClass("physics-disable");
    engine.add(set);
});

From a "Viewer" to an "Engine"

A collection of thoughts as I move surfacecurve-gfx, which is in the infancy of its development, from being a naive library capable of displaying graphics to an engine capable of simulation...

Separation of Concerns

The first concept of interest is separation of concerns. I generally file this under the principle that good software should "reduce and remove all unnecessary dependencies." In this particular case, it means consider how "viewing" a virtual scene is just one concern. Physics is another. There needs to be an engine layer that coordinates these separate concerns and these separate subsystems. Right now the code largely is just a graphics viewer.

A Separate Engine Layer

The engine layer is needs to act as a supervisor or a conductor (as in of an orchestra) that manages the separation of concerns.

It should understand what needs to happen without cognizant of the details of how. The subsystems handle the how. The engine coordinates communication, sharing, and timing: it organizes without doing the actual work itself.

Data Format Pipeline

Another concept hurdle is that of data format. The engine works with a pipeline of formats:

  • A user specified scene description optimized for convenience and clarity for the user
  • A normalized internal format optimized for uniformity, flexibility, efficiency, stability, and clarity of the code
  • Subsystem specific caches optimized for performance and stability of the particular subsystem

In a simulation environment, the user will want to update "user" objects that have already been actively converted to and are being used in the internal formats -- including subsystem caches. A mechanism is needed to coordinate changes made at the user-level (optimized for intuitive usage) with the lower-level formats. This needs to work as efficiently as possible without introducing a complex, data-duplicating (i.e. bug gravitating) bookkeeping system.

Operations

The engine, in general, needs to support the following general operations on objects in the "world":

  • Find
  • Add
  • Modify
  • Erase

In other contexts, this is referred to as "CRUD", but well -- this is a hobby project so I'm letting my subjective dislike of this somewhat standard acronym decide to go with a "FAME" system instead. I also consider "Find" to be more than just read -- it means support for searches, filters, and general queries over the whole dataset - not just operations to open one object.

What is the Engine?

The engine is largely a database, with understanding of a special kind of time-based updates.

It conceptually should the understand the following:

  • A collection of general entities
  • A collection of general instances
  • The notion of an active set
  • Support for multiples Indexes
  • Support for update frequency
  • A notion of local operations
  • A notion of global operations

Entites versus Instances: the entities in the system are the "source elements" of the engine - objects that contain all the necessary data to produce all the instances needed to represent that entity. For example, consider a particular system: it is an entity that produces a host of instances (the particles). The distinction is helpful for serialization, paging, as well as updating and level of detail. For convenience an instance should be allowed to be treated as an entity (at least conceptually) to prevent an unnecessary wrapper layer.

Active set: the engine also has the notion of "views" of the data, with the presumption that the full dataset is not needed a "full resolution" at all times. These words in quotes are intentional to convey the sense of generality in those statements. This notion of an active set implies an inherent understanding of caching and self-aware performance tuning.

Indexes: the engine should support pluggable indexes that support range queries: by viewpoint, by property, by whatever metric is needed. The engine should not care how these are implemented but should understand what they do to allow efficient usage and maintenance of the indexes.

Update frequency is related to the notion of the active set. The engine does presume the notion of a simulation over time. It expects objects to update according to some temporal/spatial pattern and will optimize for that in terms of both runtime performance and coding clarity.

Local vs Global: the engine has an explicit understanding of operations that work on an explicitly defined set of objects with no external dependencies or side-effects versus global operations where, theoretically, any object in the database could affect another operation. It makes this distinction explicit again to optimize performance by knowledge of algorithmic and data dependencies.


Projects

Libraries

  • surfacecurve-color
  • surfacecurve-blender

Sandbox