Monday, October 03, 2005

Fond Adieu.

I think this is probably the last post for this blog.

I've taken a new position as a physics research assistant at the south pole of the earth, where i'll be from about mid-october 2005 thru november, 2006.
There's more info (and a blog) here:

It's been a pleasure working with the Croquet community, and i hope to stay in touch. I'll definitely continue following the Croquet scene from down there, but i doubt i'll have time to do much more than dabble.


Wednesday, September 07, 2005

Using Shorts for spacial Coordinates

The teleimmersion project generates huge point-cloud datasets,
with approximately 100,000 points per frame, each point having XYZ and RGB data.

In the interest of increasing the performance of (future) streaming of this data from the source machines into a target machine running croquet, i've been working on simply reducing the precision of the data.

I assume a maximum streaming thruput of 18MB per second, based on tests streaming within my own computer.

Originally, XYZ and RGB were each represented as triples of four-byte floats.
So, 3 * 4 + 3 * 4 = 24 bytes per point * 100,000 = 2.4MB per frame -> up to 7.5Hz.

RGB is an obvious target, since rendering cards at their base level can only handle colors with single-byte components.

So i made an option to represent the RGB values as triples of single-byte components.
So, 3 * 4 + 3 * 1 = 15 bytes per point * 100,000 = 1.5MB per frame -> up to 12.0Hz

I'm nearly finished with an option to represent the XYZ values as triples of two-byte signed shorts.
So, 3 * 2 + 3 * 1 = 9 bytes per point * 100,000 = 0.9MB per frame -> up to 20.0Hz

Here is a screenshot showing three different types of representations.
Random-point placement aside, they look pretty much identical.

Implementation Issues

Changing to single-byte color components was relatively straight-forward.

Changing to two-byte spacial components has been a bit trickier.
OpenGL is perfectly happy being passed GLShorts for spacial data;
the card must be converting them to floats before running them thru the graphics pipeline. I haven't yet tested for performance issues here, but i don't expect any.
More complicated however is that Croquet of course works with B3DVector3, which is based on B3DFloatArray,which is based on FloatArray, which is of course, Floats.
Furthermore, Squeak doesn't even have a ShortArray!
What Squeak does have is ByteArray, which has convenience methods for accessing pairs of elements as shorts. (and longs, if you're in to that sort of thing)
So the data can be accessed for purposes such as finding bounding boxes and doing calculations.

Dealing with Scaling is so far definitely the trickiest issue.
Croquet does not use the usual scale feature of transformation matrices; rather it requires the actual vertices to be actually changed. David Smith once explained to me that this is to enable/simplify picking thru portals, if i recall correctly. In any event, i felt that reimplementing scale as a per-point conversion, multiplication, and unconversion would be prohibitively slow. So i'm trying out just putting scale right in the matrix. The sphere on the far right has been scaled this way. So far it's working well altho there must be some remaining issues with bounding box, as a TEditBox no longer works with the byte-spatial-components pointclouds. I'm about to look at this.

Monday, August 29, 2005

Cloth again

(related to this previous post)

I couldn't stay away from the cloth,
so i've put together a change set which includes a decent demo.

I added collision with spheres,
and in addition added something which altho i'm sure it's been done, i've never seen, which is: not only does cloth make way for the sphere, it also pushes the sphere around. I've only ever seen fairly static objects which the cloth humbly obeys, but it's simple enough to additionally have the cloth push the sphere.

The changeset files-in to a stock Croquet0.3 image, and is located here:

The changeset includes a pop-up menu with different preset situations.
The presets run fairly fast (20 or 30Hz or so) on my 3.2GHz windows machine,
with the major caveat that performance seriously degrades over time. I'm not sure why this is. I think it may have something to do with squeak garbage collection.

Pretty close to some initial conditions. It's billowing up because of 'wind'.
The cloth is anchored along its four edges.

A bit more billowing.

Holding a sphere. The sphere rolls around fairly nicely.

One of 8 exciting preset scenes: A sphere bowling into a cloth which is anchored only along the top edge.

Friday, August 19, 2005

Byte Color Components versus Floats

The tele-immersion data sets are point-clouds where each point has XYZ and RGB information. Previously, each of component of XYZ and RGB have been floats.
However, since colors are eventually converted to 8-bit components, RGB could be 3*8 bits instead of 3*32 bits.

Below is a comparison of tele-immersion data with 7-bit* color components versus 32-bit floats. Basically it looks fine. The 7-bit file is 2,004,809 bytes, and the float file is 3,207,668 bytes, so the ration is about 5/8!

Future directions:
I'd assumed that OpenGL required float data for XYZ information,
but i just checked and GLVertex3s is a call for specifiying XYZ with 'GLShort' components, which i presume are 16-bit. If we're able to get that to work, the data would go from 64 bits per point to only 24 bPP, or a ratio of 3/8.

Current streaming speeds indicate a theoretical maximum frame rate of about 6Hz with 64bPP, so that maximum could go up to about 16Hz, which is much more appealing.

On the resolution of 16-bit spacial information:
16 bits has a resolution of one part in 65,000.
The tele-immersion "playpen" is approximately 10 feet in each dimension, which translates to a 16-bit resolution of about .002 inches, or about .05 millimeters, which is pretty good.

* For some reason, OpenGL via Croquet interprets byte color components as being in the range 0-127, not 0-255. Values over 127 are clamped to zero. See
edit: Bert Freudenberg has clued me in that GLBYTE is a signed value; i want GLUNSIGNEDBYTE or equivelant. Thanks Bert !

Wednesday, August 17, 2005

Vernet Cloth

Dave Faught pointed me to Thomas Jakobsen's article "Advanced Character Physics", which was used by the guy who made the Falling Woman demo.
Jakobsen writes about particle systems, a subject dear to my heart, and interestingly advocates using Vernet Integration rather than Euler. I've traditionally just gone with Euler because it's straight-forward.


In Euler,
the basic per-frame per-particle process is something like:

position' = position + velocity * dt.
velocity' = velocity + acceleration * dt.
acceleration' = whatever.

With Verner,
instead of storing velocity, you store the previous position. And thus:

position' = position - positionOld + acceleration * dt^2.
positionOld = position.
acceleration' = whatever.

- I have to confess i don't understand the derivation of that core line,
but it seems to work.

Jakobsen also gives a nice approximation for square root.

So i thought i'd try out implementing the Cloth simulation outlined in Jakobsen's paper. Basically it's a triangular mesh with every edge a spring. Velocity of the nodes is not stored, but the previous position is.

A very heavy part of the computation is calculating normals.
For every node, i pre-compute a list of 2 pairs of other nodes (4 nodes total) which represent vectors to be cross-producted with each other. Essentially, for most nodes in the mesh, the node is the center of a hexagon and i calculate the normal as the cross-product of two of the hexagon's three obvious bisectors. The edges are special cases and work allright but not great, and i ignored the four corners.
To speed up normal computation, i also only calculate every Nth normal per frame. When N is 3 or 4, this is a significant speedup.

The simulation runs fairly well on my 3Ghz PC with about 25x25 nodes. Fairly well = about 20Hz or so.

Here are the change sets for the classes, and here is an image file if you're in a hurry.


Tuesday, August 02, 2005


I seem to be writing small Tweak classes lately.

This afternoon added "CInputFieldWithReset" to allow users to easily reset the values in the primitive properties editor dialog.

This object is available here:

Thursday, July 28, 2005

Input Validation

This is kinda neat.

With the new Properties editor for primitives,
there's a number of input fields which need to have the user's input validated before being used.

For example, maybe the user types in a word where a number is wanted,
or enters a value outside of the allowed range,
(or, because i thought it might come in handy, the user types in 0 when 0 in particular is disallowed).

Validation becomes somewhat trickier when the fields affect the scene immediately - that is, as soon as the user hits a key, it's reflected in the scene. In this situation, you absolutely need validation.

For example, in the case of TSphere segments, the minimum value is 2 (altho i'm using 3).
A natural and frequent user interaction will be to delete the value currently in the field and then type in a new value. After deletion but before typing, the value of the field is invalid, and so must be handled.

I subclassed CNumberConverter and added members for min, max, zero disallowment, as well as a pointer (?) back to the CInputField itself, and some helper variables.
When the input goes invalid, the CInputField background is changed to lightRed (the man's pink!) and the last valid value is reported. The text content of the input field is left unchanged, however, because changing would interfere with the user's typing.
When the input goes valid, the background color is changed to the CInputField's container's background color, and the current value is stored as the last valid value.

Basically, it works fairly nicely.

The file-outs of the new classes are here.