Thursday, October 28, 2004

Turing Lecture - Oh Canada


Bridge-7
Originally uploaded by Croqueteer.
Here it is - the grand finale. All we did here was slowly turn on the flag texture opacity, while at the same time we turned off the wireframe's. While we were doing this we played the Canadian National Anthem. Why Canada? The talk was in Vancouver, it's a good song, and the Canadian flag size is an exact 2 to 1 ratio making it an ideal flag for building bridges out of.

The code is described in some detail in earlier posts - nothing was done here except some hacks for scripting and setting the initial conditions. Otherwise, this is pretty much the TTapestry object that I created earlier.

Turing Lecture - Release


Bridge-5
Originally uploaded by Croqueteer.
Here we see the bridge breaking away from its moorings. In this case, we had set any mass that we did not want to move to have a mass value of 0. This meant that it's location would not be modified in any way. To release it, all we did was set it to a non-zero value, and magic happens. The other thing we did was set the left top mass initial location to be in a different location. When this happens, AND the mass is 0, the mass will move -slowly, to this location if it is different from whereever it is currently.

Turing Lecture - Add Wind


Bridge-4
Originally uploaded by Croqueteer.
This adds a wind force to all of the masses in the scene. This wind is generated as a vector centered at the tip of a cone and following the cone. Put your arm out in front of you and draw a circle. This wind vector is your arm. At this point, the bridge starts waving around in space reminding us of the Tacoma narrows bridge.

Turing Lecture - Change Spring Constant


Bridge-3
Originally uploaded by Croqueteer.
This script allows us to modify the springs that make up the edges of the bridge. Remember that the spring doesn't generate any force when the x in -kx is 0. x in this case is the delta from the spring at rest. That is what this computes. Here we changed the k value from -1400 which is a very stiff spring, to -400, which is quite a bit softer. Less force is generated from the same delta x. Note that the bridge is now sagging significantly more now.

Turing Lecture - Add Gravity


Bridge-2
Originally uploaded by Croqueteer.
This is a (simulated) scene from Alan's Turing Lecture. This is a pseudoscripting system that Andreas put together last week to match the look of the etoys system and present the code in a bit more readable form. Otherwise, this pretty much the same code for the flag as seen below. This is real code - we are indeed modifying it as the system runs and not only that, but it is being done collaboratively, so if we had mutliple machines running this they would all recieive the same new code and compile it.

Here we are comuting the acceleration of the mass from the force and then computing the new velocity and new mass location from this. The last line sets the initial force to a downward gravity of -2.5. The other two values in that vector are there to create noise.

Wednesday, October 27, 2004

Back from OOPSLA

Just arrived back home. I will write about the demo that we did for Alan's Turing Award Lecture tomorrow. Alan received a standing ovation for his talk, and I must say it was the best one I have seen him give. It was concise and quite powerful. The demos he did at the end were a strong demonstration of the truth of his words. I was inspired. Time to take back the night...

Test Flickr to Blog


Bridge-1
Originally uploaded by Croqueteer.
I have a number of images I want to include in these discussions, and Flickr seems to be a convenient way to do this. Full disclosure: One of my friends and colleagues - Frank Boosman - is on Ludicorp's board, but that has nothing to do with why I am using it. It is convenient.

Friday, October 22, 2004

Turing Demo

I have been working on a new Croquet demo for Alan's Turing Award talk at OOPSLA next week. I just tried it out on my son and his friend, and they were quite impressed, so I think it is going to go over very well. I won't talk about it any more here, because I want it to be a surprise for people, but once it is done, I will post it so everyone can play with it.

I have two major things left to do before I jump into the documentation again. First, I have to fix the Wicket CAD system - for some reason the handles around the TEditBox are now in the center. Very strange, and I am pretty sure this was fine when I used it to test Jasmine's recursive meta fix.

The other thing is there are still a few loose ends on some of the objects not working properly for multi-user. Will fix that soon too.

I got four hours of sleep last night. This is fun, but I am getting old....

Thursday, October 21, 2004

I need...more speed...

So I fixed a nasty bug in the rendering code that was causing everything in the Mars and Aqueduct worlds to run 1/2 speed. What was happening was the models that make up these scenes were being installed into the TQuadTree object twice when it was being constructed. This means every single element got rendered twice. Hence, not only did it seem like it was running at 1/2 speed - it probably was.

A TQuadTree is an object that breaks space up into four quadrants - I call them top left, top right, bottom left, and bottom right. Each of the quadrants is actually a TQuadTree itself and is in turn broken up into four quadrants. In theory, this recursion can continue infinitely, but in reality, I stop after a depth of 5. Also, if a quadrant would otherwise be empty, it is set to nil.

We actually create the TQuadTree object with the act of dropping a collection of frames into it. Each of these frames has it's own boundSphere around it, and we compare this to the size and location of each quadrant. If the object can't be put in one of the sub-quadrants because it is too large, we just leave it at the containing quadrant. Thus, each sub-frame eventually comes to rest at the quadrant that best approximates it's size.

So why deal with QuadTrees? The idea is that an object is easier to find (for picking or rendering) by traversing this tree of quadrants. Objects are placed into the TQuadTree based upon location and size. For example, if you need to find a point directly underneath you, you already know which quadrant you are in, so you can test just that one. If that fails, you can test it's subquadrants, etc., until you find an object to stand on. This is ignoring the fact that objects tend to overlap quadrant boundaries, and in fact I deal with this as well. The TQuadTree is what is known as a loose quadtree. That is a quadtree that allows overlaps, but requires that you test all of the edge quadtrees as well. This works surprisingly well, as we only need to put an object into the quadrant that contains it's center point. If you don't use a loose quadtree/octree method, you can use a strict method, but this requires you to duplicate the object in all of the quadrants it overlaps.

The other win that quadtrees like this gives you is improvements in rendering speed. If a quadrant is visible to the camera, then it is quite probable that the contents of that quadrant will be as well. More importantly, if a quadrant is NOT visible, then we have a guarantee that it's contents are not visible. The same overlapping/neighboring quadrant test applies to rendering as well.

One way to think of the process of constructing an octree is that of a collection of sieves- one on top of the other - with the ones with the larger holes on top, and smaller holes as you go down from there. The objects that make up the scene fall through the larger ones until they no longer can fit in the lower ones. When the sorting is all done, each object is at its proper location in the sieve.

One other benefit that loose quadtrees give you is it is much easier to move an object around in one of these. Since only one copy of the object exists in the tree - we need only move it from one quadrant to another when it's center point has moved across the boundary between them. Bookkeeping is extremely simple.

Tuesday, October 19, 2004

Rendering Speed Problem

The Jasmine release of Croquet seems to be about half the speed of the Solar version. Andreas said he thought it might be due to the objects like the TFlag constantly running in the background, but I don't think so. In addition, the PC version seems to be running much faster than the Mac, where in the past they were about equivalent. Again, not sure why. I don't think that the rendering pipeline is that much different between Jasmine and Solar. I thought it might be a texture issue, but turning off texturing entirely makes little difference in performance. The good news is clearly once we fix this, everything runs a lot faster.

Sunday, October 17, 2004

Blogger = Poor formatting

Blogger does a particularly poor job of formatting just about everything. It is certainly easy to use, but the quality of posts, especially things like code, and the way it handles emailed blogs is unacceptable. If anyone knows a better system, please let me know.

As an example, spaces are as important in a sentence as the words.

Obviouslythisishardtoreadandyouwouldneverdothis.

Unfortunately, I can't show you an example where multiple spaces add to the meaning of a sentence, because BLOGGER STRIPS THEM OUT. What is worse, they had to write code to do this, as the text would have printed just fine otherwise. In fact, it looks fine in the editor. This is stoopid.

How to render the Flag

Croquet uses OpenGL so rendering the TTTapestry is just a series of OpenGL calls. You can find this code in the recent Croquet updates as well.

The basic idea is the masses are objects that include their position in space, the normal that is computed from their neighbors, the texture u,v location which are all used in rendering, and the summation of the forces from the springs, gravity, and wind. The mass position is an obviously useful thing to have around. This is used both to render it here and to determine how much the TSpring is stretched to determine it's restoring force.

The normal is used by both the wind vector to determine how much of the face of the flag is facing the wind. That is, a piece of cloth that is perpendicular to the wind feels a strong force, where one that is parallel doesn't feel much at all. It is also used in lighting the flag, as the amount of light at this location is determined in much the same as the amount of force from the wind is.

The texture u,v coordinates are usually a number between 0.0 and 1.0 and determine what part of the flag's texture corresponds to this mass location. The texture is then stretched between the other mass locations and this one.

This method uses a triangle strip method. It is actually kind of a zig-zag like this:

1--------2
--------
------
---
3--------4
--------
------
---
5--------6

...


We have to make a number of top to bottom strips like this to complete the flag, so it looks a bit more like this:


1--------2--------n
-------- --------
------ ------
--- ---
3--------4--------n+1
-------- --------
------ ------
--- ---
5--------6--------n+2


TTapestry>>#render: ogl
"We always pass in the OpenGL object when we render"
| index m |

ogl glDisable: GLCullFace. "we want to render both sides"
texture ifNotNil: [ texture enable: ogl.]."activate the texture"
1 to: xsize-1 do:[:i | "this is left to right"
wire ifFalse:[ ogl glBegin: GLTriangleStrip.] " if this is wire frame"
ifTrue:[ ogl glBegin: GLLineStrip.]. "or if it isn't"
1 to: ysize do:[:j | "draw the strips vertically"
index _ (i-1*ysize)+j. "location of the mass in the big array"
m _ masses at: index.
ogl glNormal3fv: m normal. "computed from nearby masses"
ogl glTexCoord2f: m uv x with: m uv y. "texture coordinates"
ogl glVertex3fv: m location. "continue line at 3D location of mass"
index _ index +ysize. "index of the mass to our right"
m _ masses at: index.
ogl glNormal3fv: m normal.
ogl glTexCoord2f: m uv x with: m uv y.
ogl glVertex3fv: m location.

].
ogl glEnd. "stop rendering the triangle strip"
].

"If we are rendering in wire frame, clean up the edges, otherwise we have
a zig-zag like shape."
wire ifTrue:[
1 to: xsize do:[:j |
ogl glBegin: GLLineStrip.
1 to: ysize do:[:i |
ogl glVertex3fv: (masses at:(j-1*ysize)+i) location.].
ogl glEnd.
].
].
texture ifNotNil:[texture disable: ogl.].
"
This was test code to render the springs to see if these make any sense...
they do now.

springs do:[:s |
ogl glBegin: GLLineStrip.
ogl glVertex3fv: s mass1 location+(0@2@0.3).
ogl glVertex3fv: s mass2 location+(0@2@0.3).
ogl glEnd.
].
"
"
This was test code to display all of the normals on the flag.

masses do:[:ms |
ogl glBegin: GLLineStrip.
ogl glVertex3fv: ms location.
ogl glVertex3fv: ms location - ms normal.
ogl glEnd.
].

"
"return OpenGL back to it's standard approach of culling back faces"
ogl setCull.

Saturday, October 16, 2004

Flag Time to Run

Here is something interesting. I compared the two compute engines of the old TFlag and the new TTapestry and found the following:

tf := TFlag new.
tt :=TTapestry new.

( the results are in milliseconds)
[1000 timesRepeat:[ tf step ]]timeToRun 8608
[1000 timesRepeat: [tt testCompute]]timeToRun 9528


[10000 timesRepeat:[ tf step ]]timeToRun 80553
[10000 timesRepeat:[ tt testCompute]]timeToRun 92868

I presume that what this means is the much simpler code of TTapestry, which yields nearly identical qualitative results does not take that much longer than the array juggling that TFlag has to do.

A fifteen percent increase in compute time is a small cost to pay for the code being so much more readable. Also, though I can't imagine where I could speed up the TFlag computation, as it is so complex, I am sure I could easily find a few additional cycles in the TTapestry. But then, perhaps I am missing something?

The new classes are posted as Croquet updates. See TTapestry for how to use.

Thursday, October 14, 2004

At Jawjaw Tek

Alan gave his dry-run talk for his Turing Award talk later this month (which was excellent by the way). I was supposed to demo the mass/spring model I did with him at the end, but did not realize he was waiting for me to let him know I was ready - and I was waiting for him to let me know when to come up to do it. Oh well. I expect the demo will be in great shape for the next talk. Besides, I think his talk was actually quite well done without my demo at the end. I think it might have broken his stride.

The demo is actually quite simple. There are three objects. What I call a TTapestry, which is the UI and rendering of the system, a TMass, which holds a position, summed forces, and a mass (usually 1.0), and TSpring, which connects two masses.

When initialized, TTapestry creates a grid of TMasses, roughly in a square, and generates a collection of TSprings, each of which is iniitalized with two masses that can have influence on each other. All three of these have a #compute method. The TTapestry compute sends the other two compute messages to the collection of masses and then springs.

TTapestry>> #compute

self addWind.

springs do:[ :s | s compute. ].
masses do:[ :m | m compute. ].

self future: 20 perform: #compute.

the #addWind message just adds another force to the masses from a virtual wind.

The TSpring>>#compute uses the standard -kx force computation as below:

TSpring>> #compute

| v n k |

k:= -200.0.
v _ (mass1 location - mass2 location).
n _ v normalized * rest.
v _ (v-n) * k.
mass1 addForce: v.
mass2 addForce: v negated.

All that this is doing is determining the vector distance between the two masses, subtracting the rest distance (where the x in -kx is zero) and then multiplying the rest by k. We then add this force and its equal and opposite reaction force to the appropriate masses.

Finally, we compute the effect of the forces on each mass:

TMass>>#compute

| g accel t |
mass ~= 0.0 ifTrue:[
t := 0.05.
g := 0.0@-2.0@0.0.
force := force + g." add the gravity"
accel := force. " mass = 1.0"
velocity := velocity + (accel * t). "acceleration increases velocity"
velocity := velocity - (velocity * 0.1)."damp velocity"
location := location + (velocity * t). "change location"
force := 0@0@0. "clear force"
].

if the mass is 0.0 we don't do anything, as this means the mass is a fixed location - like the corner of the flag.

We could use the actual elapsed time here, but I am just using an artificial one, which I am setting to 0.05 of a second. I am presuming that the mass is equal to 1.0 so I don't have to divide to compute acceleration (f = ma, hence a = f/m).

Acceleration causes a change in the velocity, and velocity causes a change in position, so now we have moved the location of the mass.

This last line is very important. Now that we have resolved the forces from this time segment into an action, we need to clear the force vector. If we don't, this force value will continue to grow, which causes the system to become unstable.

That is all there is for the masses and springs. Really. The TTapestry adds a wind, but this just results in another force being added to the masses. What I find so interesting is that these two extremely simple objects generate such interesting behavior.

The only other interesting thing is the TTapestry>>#render:, but for some reason I screwed this up, so need to thing about it a bit before I post it here...

Wednesday, October 13, 2004

Off to Georgia

Alan is giving a talk at Georgia Tech tomorrow and asked me to come along for the ride. Things look pretty good - I think we will have a much more robust version of Croquet by tomorrow than Solar ever was. By the way, Solar was our old war horse demo platform. All of the neat little demo apps we have in Croquet were built to show off in the Solar version. I called it Solar because it has a neat model of the Solar system in it. I tended to keep track of the versions based upon whatever new thing I had built in it. There is no Jasmine app - yet.

Alan wants a demo that is kind of a cross between the flag and the CAD system. For tomorrow's talk...

I have been thinking about this for a bit. I have some interesting ideas which I will probably write about later.

Tuesday, October 12, 2004

Jasmine Debugging

I must have killed a dozen bugs today already. Most of them are between the crack bugs - that is, bugs that were created by porting the MadHatter architecture onto the Solar replication model. Nothing fundamentally wrong, just tracking them down and checking with Solar on how the objects computation should be replicated.

There is one potentially serious problem that I am in the middle of fixing. When an avatar traverses through a portal into another space, currently the remote version of the avatar is not making the transition. The reason was pretty simple - the transition was never sent remotely. The problem is that we send the following message:

avatar future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

which is in effect telling the avatar to jump through the portal asap. What we really want is

avatar meta future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

Subtly different and guaranteed to lock up the system. Why? When we send a message between machines that reference TObjects like the avatar, we don't send the actual object - we send it's name. The target of the message is encoded as well as the arguments. The problem is that this is not done recursively. That is, the actual message that is being sent here is

#future:perform:withArguments:

and its arguments are the message #goToPortal:transform and... an array. We don't do a recursive lookup. That means that we try to send the array and it's contents in toto. Well, in this case, toPortal is a member of the array and is also a TObject that is somewhere inside of a space. It is actually a TPortal, but that doesn't matter. What we are trying to do is package up the TPortal and everything it references and send that. This will fail because we are trying to send the entire contents of the croquet session that probably references all of the Squeak image in some way. Not particularly efficient.

Squeak actually has something that is designed to address this problem that I used in a previous version of Croquet. Unfortunately, I can't find that code exactly, but it is based upon a SmartRefStream, which in turn is a subclass of RefStream, which is simply a way to convert objects to streams and back again. A SmartRefStream is "smart" because it is very aware of multiply referenced objects and can eliminate redundency - very important if you don't want to turn one local object into multiple remote objects. What I did before was added a bit of code that would dereference the objects to their TeaNames if they had one, otherwise it would just encode the actual object.

Once this is in place, then remarkably,

avatar meta future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

will just work.

Magic.

Monday, October 11, 2004

Jasmine Ships - ReadMe.txt

We just agreed to release Jasmine to the public today. This was a
pretty intense effort. Andreas and I spent two weeks together to port
the new architecture that we did for MadHatter to Jasmine, and then we
seriously upgraded the meta architecture. The last week has been spent
on documentation (still not ready), debugging, and finishing off as
many loose ends as we could. Interesting that the very last thing we
had to do was decide on the name of this release. We all finally agreed
that this is, in fact, Croquet 0.1. This is to ensure that people
understand that this is an early incomplete version of the system. The
"Jasmine" term is the project/release name, so this will change for
every major release that goes out the door.

As always after a release, I am a bit drained rather than exhilarated.
I tend to dwell on the things that are missing and the problems that
are still in the code. Ignorance is bliss - and I just know too much.
Anyway, here is the Read Me from this release (or a close
approximation):

READ ME - Jasmine 1.0
The Croquet(tm) Developer's Release
-----------------------------------------
The Croquet Committee welcomes you to the Jasmine Developer's Release
of Croquet.

The Croquet Home Page is at http://www.croquetproject.org. Everything related to Croquet is accessible from there, including access to the Croquet system itself.

The Jasmine Developer's Release is intended for people to get their feet wet playing with Croquet. Though most of the system is functional, some key elements are not quite ready and will begin to appear over the next few weeks. This release is really to get you acquainted with the system, deconstruct the examples, and try your own hand at making some things. It is important to note that Croquet is built on top of the Squeak system and includes a complete development environment. In other words, everything you need to develop in Croquet is included as part of this release.

Croquet is an true Open Source project and is covered by an MIT type license. With that in mind, we invite you to participate in the ongoing evolution of the system. You can do this in a number of ways.

First, we have a community mailing list that you should join. You can
do this at:
http://www.croquetproject.org/Community/listserver.html
This is probably the best place to have your questions answered and for you to help others figure out how to extend Croquet.

Second, we have set up a bug tracking system at
http://bugs.impara.de
You will need to register to use this, but it allows you a place to let us know about any problems that you might have.

Third, you can help by providing us with bug fixes, new features, or just new ideas. Many of the things that we use to demo Croquet came from people who had a neat idea that we just had to implement.

Fourth, let us know what you think. In the end, we are doing this for you. We are truly interested in what you think of what we have done, where it could go, and where we failed. Even if you hate the system, let us know - you could well know something we don't. In the end, we can't make Croquet great without your help.

Launching Croquet
-----------------------------------------
Croquet runs on three different platforms - Macintosh, Windows, and Linux. Each of these have slightly different methods for launching the system. Once you are actually running Croquet, all of the systems work identically. All of the Jasmine folders include essentially the same files. The Jasmine1.0.image and Jasmine1.0.changes are where the actual Croquet system is, but we have made it easy for you by supplying a launch icon.

Macintosh: To start Croquet on the Macintosh, just double click on the "Jasmine" app in the folder.

Windows: To start Croquet on Windows, simply double click the "Jasmine" shortcut that you will find in the Jasmine folder.

Linux: To start Croquet on Linux, simply double click or run the "Jasmine.sh" file.

Getting Started
-----------------------------------------
When you start Croquet, you will see three small window icons (along with the license). To jump into Croquet, just click on the icon labeled "First Steps". This takes you to another desktop where you can begin to play.

1) Press the 'update code from server' button OFTEN and REGULARLY. This will keep your system up-to-date with the latest developments (you can also update the system through the world menu, 'help...' submenu). It is extremely likely that by the time you read this, the system will have a number of updates available that may directly address potential problems that you might otherwise have. Don't wait.

2) Drag one of the four objects from the catalog to the center of the main window. The standard Croquet demo can be accessed by dragging the 'Teapot' object (be warned that because of the amount of stuff in the demo - it may take some time for it to completely load - this WILL improve dramatically).

From this point, you can just experiment. For information on how to maneuver through the Croquet system, please check out the web site user guide at:

http://www.croquetproject.org/About_Croquet/userguide.html

Note to Programmers
-----------------------------------------
Croquet is a component-based architecture that makes it extremely quick and easy for you to create useful collaborative objects. The system has been designed from the ground up to make it simple to create truly shared objects of virtually any sort.

For basic information on how to approach programming in Croquet, please
refer to:
http://croquetproject.org/croquetdevelopment/Croquet_Technologies/programmer.html

(Please note that this site does not attempt to teach you how to use the Squeak programming environment, or how to program in OpenGL. There are a number of useful resources available for both of these, includingĂ‚  Squeak: Object-Oriented Design with Multimedia Applications by Mark Guzdial, Prentice-Hall, 2000, and the OpenGL Programming Guide by Mason Woo, Jackie Neider, Tom Davis, and Dave Shreiner, Third Edition. Addison-Wesley. 1999). You will also be able
to download the Croquet Manual from:
http://www.croquetproject.org/Croquet_Technologies/downloads.html

Bug Reports
-----------------------------------------
We have a bug report server running at http://bugs.impara.de. Please let us know of any problems - major or minor.

FAQ
-----------------------------------------
For more information about Croquet and the Jasmine release, the Croquet
FAQ is available at:
http://www.croquetproject.org/About_Croquet/faqs.html

Croquet License
-----------------------------------------
Copyright (c) 2002-2004 by Viewpoints Research Institute, Inc. and other individual, corporate, and institutional contributors who have collectively contributed elements of the Croquet(tm) software code to the Croquet Project. Croquet is a trademark of Viewpoints Research Institute, Inc..

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.




DAS

Wednesday, October 06, 2004

Croquet Anyone?

Hi all,

Thanks for your patience. The developer's release of Croquet (codenamed
"Jasmine") is undergoing some final Q&A prior to being made available
for download on Monday, October 11 here:

Croquet Project DownLoads

Jasmine will allow you to begin developing components with some level
of comfort that the interfaces will not change significantly between
this and the user release. That said, there are a number if important
pieces still missing, but we are quite comfortable that these will be
available soon and have decided that there is no reason to wait for
them before releasing the system. Please let us know of any problems
you might run into or ideas for improvement that you might have. This
release represents a major turning point in the evolution of Croquet -
from a closed development effort to one that is open and truly takes
advantage of the dynamics and capabilities of the open source
community. Thanks again for your support.

Best regards,

David