Wednesday, April 27, 2005

Fedora Core 3 and User-Mode Linux

Previously, I made a Fedora Core 3 disk image for User-Mode Linux by simply copying the disk image of a running system into a loopback disk image and starting User-Mode Linux using that disk image. That works, but I later found that some of my services didn't start up correctly in UML.

It seems that Mysql doesn't work with the current User-Mode Linuxes based on 2.6 kernels. Apparently, UML doesn't implement some of the new threading features of 2.6 kernels, which causes various problems. To avoid that problem, you have to erase the libraries that use these new threading features. I found a forum that listed this fix

mv /lib/tls /lib/tls.backup

that prevents the libraries that make use of the new threading features from being found. While you're at it, it's probably also a good idea to disable the SELinux features because they haven't been designed to be easily configurable in Fedora Core 3 anyways. Just modify /etc/selinux/config so that SELINUX=disabled (instead of "enforcing").

I also had problems with postgresql, but that was because I forgot to make /tmp world-writable. Unfortunately, my postgresql didn't seem to log anything, so I couldn't really diagnose the problem. I tried to play with the boot commands a bit to get it to log something, but in the end, I found it was easiest to simply run the postgres postmaster from the command-line with

su postgres
postmaster -D /var/lib/pgsql/data

Currently, my Fedora Core 3 image for User-Mode Linux seems to be running fine. httpd does seem to crash the UML kernel when it exits, but I can live with that for now.

Sunday, April 17, 2005

U3D is Half-Baked

So during the weekend, I decided to try writing a U3D file viewer. I had high hopes for U3D because U3D seemed to avoid many of the weaknesses of the competing X3D specification. After working with U3D for a bit though, I've concluded that the U3D specification is half-baked. It's almost as if the 33 members of the 3D Industry Forum performed almost no due diligence in reviewing the specification. Personally, I think the spec is unworkable and unimplementable. This is a real shame because Adobe went and added U3D support to Acrobat, meaning that a lot of marketing muscle and mindshare has just been put behind a losing proposition. Even if a better spec were designed in the future, since it wouldn't be supported in Acrobat like U3D, it would likely fail.

I can ignore minor annoying aspects like the fact that the spec itself wasn't well-designed, treating things like arrays in several different ways throughout the spec and going out of its way to avoid simplifying the descriptions of the fields, and such.

But the killer of the spec is its ridiculously overbearing bit encoding scheme. I just cut & paste the code from the specification and translated it to Java, and it's just awful. The code uses something like over 30 lines of code to read an uncompressed 8-bit integer. And the encoding/compression scheme has some characteristics that simply ruin the rest of the specification.

For example, the compression scheme sometimes requires you to feed in parameters of live data structures in order to read subsequent data. This means that you can't simply read the data into data structures and then process it later. You literally have to create a live mesh data structure, manipulate the mesh as data is being read in, and feed the resulting properties of the mesh back into the compression scheme in order to read the next bit of data.

And the encoding scheme has this weird property whereby previous data values read can influence future data values read. So even though the file format is supposedly tag/block-based (meaning that you should be able to process only the types of data that you are interested in and skip the rest), you still need to read, process, and understand every single bit of data in a file in order to read later bits of the file because otherwise the decoding state won't be properly configured when you get there. This even holds true for uncompressed data, which is just wonky. I wouldn't have believed it if I couldn't see it right there in the code that I cut & paste from the spec.

After having spent something like 5+ hours on trying to read in a CLOD Progressive Mesh Continuation Block from a file and failing miserably, I can only conclude that it's simply not worth the trouble to implement. I am now very suspicious about why the 3DIF still hasn't released a reference encoder/decoder three months after the release of the specification. In any case, as far as I'm concerned, U3D is a write-off. It might gain a little bit of mindshare because of its Acrobat-support, but I think it will eventually die off because the only way to create U3D files is to use the rumoured Intel SDK (since it's essentially impossible to write one's own encoder), and most 3D tools developers will decide to ignore it.

Friday, April 15, 2005

Some First Impressions on the U3D Format

I haven't actually done any examining of U3D files yet, but I did a quick skim through of the specification, and I have a couple of first impressions.

The first thing I noticed was that they put a "file size" field in the file format. Personally, I think no self-respecting file format includes a "file size" field. The inclusion of such a field makes it impossible to stream data to stdout. Instead, you have to write out all the data, then rewind all the way back to the beginning of the file, just to fill-in that field. It would be different if the field served some sort of useful purpose, but I imagine all U3D file readers will just ignore it.

Then, the basic geometry type of the file format is the Continuous-Level-of-Detail (CLOD) triangle mesh. This is a little unusual because I thought the consensus in the 3d graphics community was that no one actually uses this stuff (of course, not being in the 3d graphics community myself, I can't be 100% sure, but that's the impression I get from reading papers). The main uses of CLOD meshes are for progressively refining 3d models during data streaming and for animation. I think the Internet experience has been that progressively refining anything during data streaming just isn't worth the trouble. For example, who uses the "interlace" option on their PNGs and GIFs? And properly getting the synchronization right on browsers so that they can handle the rendering of partially downloaded files is just a big mess. Just look at the old Java image APIs that supported these features: they were almost unbearable to use. It's easiest to simply use less-detailed thumbails/models. And I think CLOD meshes aren't used for animation either. If refined versions of CLOD meshes are computed by the microprocessor, then they have to be transferred to the video card for rendering, which is a waste of video bandwidth. It may be possible to do the refining of CLOD meshes on the video card, but I think no one does this because a) it's hard, b) CLOD meshes take up a lot of memory c) refining CLOD meshes aren't easily parallelizable and exhibit poor memory access behaviour d) you can get nicer looking low-polygon models by editing them by hand and using bump-maps and stuff. I suspect that the only reason CLOD meshes were included in the specification is that Intel wanted them there, but I would have thought that the rest of the 3DIF members would have convinced Intel to leave the feature out for the first version and only include it in version 2.0 (and then decide never to release a version 2.0 of the specification). I think it's possible not to use the CLOD mesh features though.

The U3D file format also uses a large variety of data types. I guess it isn't a real problem, but in this age where bandwidth is cheap (and things can be compressed fairly efficiently anyways), I think it makes more sense to have a couple of floating point types, an integer type, a byte type, and that's it. I haven't really examined what all the different types are used for though--there might be a good reason.

And the "U3D" way of doing things means that most resources are given string names. This seems a little inefficient (especially if you use something like UTF-16 encoding). It would seem to me that named resources would be more the exception than the rule, so it would make sense to have most resources be unnamed, and provide an optional naming interface for those resources that do, in fact, need names so that they can be accessed externally.

Also, the file format uses some weird lossless compression scheme. If the compression scheme were decent (like, say, the lossless compression that comes with jpg, mpg, and png), then I guess it might be worthwhile, but it looks like it's possible to get even better compression just by feeding the data into a zip compressor, so I'm surprised they even bothered.

I haven't really dug all that deep into the U3D file format yet though, so until then, I can't really say anything intelligent about the standard. But hopefully, I'll get around to doing that in the future.

Finding U3D Files

For the past few weeks, I've been wanting to play with the U3D file format a bit. Unfortunately, no actual U3D files are available on the web. There are U3D files embedded in pdf documents that can be viewed with Acrobat Reader, but if you want to look at an actual U3D file, you're out of luck. Intel apprently has a SDK for creating and reading U3D files, but they haven't released it to the public yet, so the most widespread way for people to get an actual working U3D file right now is to get a trial version of commercial 3d file format conversion software (which has Intel's U3D SDK embedded in it) and to convert some existing files over to U3D.

I tried e-mailing the 3DIF, asking them to put up a plain U3D file somewhere so that I could take a look at it, but they never bothered replying after a week. Fortunately, after a little bit of research, I found a utility called Multivalent. This utility comes with a tool called Uncompress, which is able to take a pdf document and uncompress all the files attached inside. Of course, afterwards, you still have a pdf document with U3D files embedded inside, but since the U3D data is now uncompressed, it's possible to examine the raw U3D data.

Since all U3D files start with the string "U3D\0" you can just discard all of the pdf data that comes before that string, and everything after that is a valid U3D file (I presume). I used a little Python script like this to discard the initial useless pdf data:

f=open('file.pdf')
data = f.read()
f.close()
# You need to take the second "U3D"
idx=data.index('U3D', data.index('U3D')+1)
data = data[idx:]
f=open('file.u3d')
f.write(data)
f.close()

Saturday, April 02, 2005

Maybe X3D Isn't Such a Bad Spec After All

After previously denouncing the X3D specification, I decided to take a look at the competing U3D specification. I skimmed through the specification trying to think about what would be required to implement a U3D reader (the spec mandates a binary encoding with special compression used) when I realized that there aren't any U3D files available for testing U3D implementations. Nowhere. Except when they're embedded in pdf documents. Perhaps one has to be a member of the 3dif to get access to them, but the problems I have with the X3D specification pale in comparison to the no-no of developing a specification that uses a complicated encoding without providing an example file anywhere. Well, I e-mailed the 3dif. Maybe I was just looking in the wrong places.

3D Tools for the Casual 3D Artist

Every few months, I get the urge to learn how to do rudimentary 3d art, so I do a quick tour of 3d tools available for casual users, and I always come back disappointed. For casual users, it's important that tools be cheap, not require users to have artistic talent in order to create simple objects, and be easy to use.

Immediately, the big, mainstream 3d modelling packages can be ruled out because they're too expensive. Of course, it's possible to use illegal copies of these programs, but I prefer not to do that. Then there are the mid-tier tools, but I'm always hesitant to shell out several hundred dollars for little-known tools from little-known companies that may or may not be any good.

This pretty much leaves low-cost and open source tools. The tool with the most mindshare currently is Blender. Unfortunately, Blender is a good example of a software application where little or no attention has been paid to the user-interface. If you read the development docs, this was an intentional decision on the part of the developers. For example, up until a couple of months ago, Blender proudly touted the fact that it had no undo functionality (telling you to save often instead). Personally, I'm tempted to use terms like "amateur-hour" here, but honestly, if I were a professional 3d artist who had just shelled out thousands of dollars for this tool, I would probably be ok with learning all of the weird UI quirks and hotkeys needed to be productive with the tool. Since I'm not a professional 3d artist and the tool is free, it's probably unfair of me to apply my standards on the tool. I have made a few honest attempts at trying to learn Blender, but all the hotkeys made my head spin and it seemed to crash quite often for me. Plus, based on the tutorials, it seems like users need powerful 3d visualisation skills to make effective use of Blender--skills that I don't possess. There's no way I can think in terms of "take a sphere, extrude this section while rotating it like so, perform a lathe on that object, and then edit the mesh." At best, I can look at a 3d object and play with the vertices a bit to get the shape that I'm looking for.

Milkshape3d is another popular 3d tool, and I've been tempted on many occasions to shell out the cash to go buy it. Milkshape3D is nice because it does only a few small things, but it does those things reasonably well. Unfortunately, every time I'm about to mail away my money to Switzerland, I start to think about the tedium of clicking in multiple windows everytime I want to add a single point to the model, and how I always get confused when I have to keep looking at different windows to know where I am, and I decide to wait for something better. I'm probably being hopelessly optimistic because manipulating 3d geometry on a 2d screen with a 2d input system (the mouse) is, by definition, hopelessly complex. But still, when I've used scaled back versions of professional tools (e.g. GMAX), they always provide nice facilities for manipulating polygon vertices without much hassle, so maybe that's what I'm looking for.

Art of Illusion seems to be reasonably powerful, but I think its 3d graphics isn't hardware accelerated, so it always seems a little sluggish to me. Plus, I can never figure out what the icons mean and the tooltips take too long to show up, so I spend much of my time holding my mouse pointer over icons to figure out which one does what I want.

Recently, I tried Wings 3D, and I really liked it. It's possible to perform lots of complex operations with complete ease. Pretty much all of the UI is self-explanatory and mouseable. The main advantage of the UI is that since everything is explained on-screen, you only have to memorize five things to be productive--namely what G, L, Q, space bar, and the middle mouse button do. With everything else, all you need is a general idea of what you want to do, and you'll probably be able to find it in the menus somewhere. The only problem with Wings 3d is that it doesn't work with many graphics cards. I tried it on an ATI Rage card, and an Intel integrated Extreme Graphics, and the UIs ended up being too horribly mangled to be usable. Finally, on an ATI 7500, the UI still didn't quite render correctly, but it was enough to be usable, and it was a joy to use. I was tempted to dig into the code and see if I could find any workarounds for my problems, but Wings 3D is coded in Erlang, so...yeah.

So in conclusion, if you want to dip your toe into 3d graphics on the cheap, try Wings 3D, and if it doesn't work, give up. Of course, I may be the only person who finds xfig to be an easy-to-learn program that one can quickly become productive in, so perhaps my experiences may differ from that of others.

Wednesday, March 30, 2005

Creating Fedora Core 3 Disk Images for User Mode Linux

So, for the past couple of weeks I've been working on creating a Fedora Core 3 disk image for UML. In the end, the process ended up being quite straight-forward, but in a case of "a little bit of knowledge can be a dangerous thing," I kept screwing it up.

Pretty much, all you have to do is to create an ext2 loopback disk image as suggested in the UML docs, and then copy a running fedora core system (using cp -r -d --parents --preserve=all or whatever) into it (obviously, you should avoid copying the disk image into itself). That's pretty much it. Labeling the disk image as /1 doesn't seem to be enough to get UML to mount the disk image properly as its root file system, so you do have to modify the /etc/fstab file so that the root file system is mapped to /dev/ubda (for some reason, the virtual drive appears as /dev/ubda instead of /dev/ubd/0 like in other images) using an ext2 format (unless you compiled ext3 support into the kernel). It's probably a good idea to enable networking in the kernel as well by turning on these kernel options:

UML Network Devices/Virtual network device
UML Network Devices/TUN/TAP transport

Then, you can just boot up UML into the image you created. You don't have to change the Kudzu configuration, change the networking to use something other than eth0, or anything. It just works. Below are the things I tried to do, which ended up being completely unnecessary:

Although Fedora Core 3 intially boots with a small initrd RAM disk image as its root file system before switching to using the hard disk as its root, this initrd is only for loading additional kernel modules. Since User Mode Linux has most options compiled directly into the kernel, it is not necessary to use an initrd image with UML. Also, it is not necessary to create ubd devices in /dev since Fedora seems to do that automatically. And hostfs mounting /sbin or /bin doesn't work out too well. You can mostly get away with hostfs mounting /usr but you have to prevent xfs from starting up (simply remove /etc/init.d/xfs) because I think it tries writing stuff into /usr, which won't work because on the host-side, UML won't have sufficient permissions to write there. I also didn't bother properly installing uml-tools, meaning that UML couldn't use the port-mapper to bring up the virtual console xterms. Since Fedora Core 3 requires you to log-in through a virtual console, you need to get the port-mapper working properly (I had to modify UML to find the port-mapper in my home directory instead of its default location). Also, Virtual Console #7 and #8 won't appear or won't show anything, so don't think the boot-up has failed if you don't see anything there. And that pretty much summarizes many, many days of mistakes.

Monday, March 21, 2005

Off-Screen Buffers in Java

I recently discovered that off-screen buffers in Java can be really slow. Off-screen buffers are commonly used in Java games so that a frame of animation can be constructed and then displayed on the screen without resulting in flicker. Since the Swing toolkit is double-buffered, most applications don't normally need to create their own off-screen buffers, but I don't like using the UI thread for game logic and rendering in my games (plus my games use AWT), so I have to manage the off-screen buffers myself.

Anyway, many graphics operations in Java are not hardware accelerated yet, and some of the buffer code that I'd been using for a long time has been using some really slow operations; I'd simply never noticed until I started working on a computer with a really old PCI Rage 128 graphics card. With such low bandwidth across the PCI bus, blitting the off-screen buffer images to the screen ended up being really, really slow.

The problem is that I'd created the BufferedImages backing the off-screen buffers as TYPE_INT_ARGB. I think the inclusion of an alpha channel, combined with an assumed lack of hardware acceleration, resulted in a lot of data needing to flow back and forth across the PCI bus unnecessarily. Once I switched the buffers to be TYPE_INT_RGB, everything was back to being snappy and fast.

Monday, February 21, 2005

Running User Mode Linux from 2.6.10 Kernel

I don't really know anything about mucking around with the Linux kernel (I'm the type of guy whose favourite text editor is pico and who can't figure out how to use Debian meaning he has to use RedHat instead), but somehow I signed up to do a term project involving a bit of kernel hacking, so I guess I have to learn. Since kernel stuff seems a bit messy, I opted to work with User Mode Linux (UML).

Now, when one browses around through the main website, there's a lot of stuff about ancient versions of UML based on 2.4 kernels, there's a couple of mentions of 2.6 kernels, and tucked away somewhere, there's a brief aside that UML has been integrated into Linux kernels 2.6.9 and beyond. Seeing as everything else on the main website seemed a little dated, I thought that it would be best to use the UML that's integrated into the main Linux branch because it would be more likely to be maintained and tested there. In actuality, the UML code that's been integrated into the kernel doesn't work all that well, and it took me a few days of searching through various websites, wikis, forum discussions, etc. to figure that out. So here are the goods on how I got UML working on my Fedora Core 3 system.

Apparently, the UML in the current 2.6.10 vanilla kernel doesn't work. Instead, grab the 2.6.9 vanilla kernel from kernel.org or somewhere. Then, go to Paolo Giarrusso's UML site and grab the latest 2.6.9 patch (it's in his archives in the guest patches section). After you've unzipped and patched everything, simply taking the default configuration from

make menuconfig ARCH=um

isn't sufficient. One has to enable these options in the kernel

Character Devices/File Description Channel Support
Character Devices/Port Channel Support
Character Devices/tty Channel Support
Character Devices/xterm Channel Support
Block Devices/Virtual Block Device
File Systems/Pseudo File Systems/dev File System Support

Then, you can follow the normal instructions about compiling, stashing a root_fs file system somewhere, and then using the devfs=(no)mount option appropriately.

This is enough to get UML to bring up a prompt, but that's as deep as I've dug so far. I'm still weighing whether it would have been easier simply to have started with a Debian package of UML.

Tuesday, February 08, 2005

CorelDraw 11 Import/Export Woes

Being from Ottawa, I'm a CorelDraw user (Corel is an Ottawa-based company). I'm not a very good CorelDraw user (I just use it to draw simple diagrams), but I'm still a CorelDraw user. Just like other CorelDraw users, I have to live with both the good and the bad features of CorelDraw. It comes with a lot of features and applications for a good price, but you have to live with the ever expanding resource usage of each version, buggy features, an under-designed user interface, and a general lack of polish. Perhaps things will get better now that they're under new management.

I bought a discount version of CorelDraw 11 a few months ago, and I use it for mostly computer science type things: presentations and LaTeX diagrams. In order to use CorelDraw in this sort of configuration, you need to do a lot of bulk importing and exporting. I just thought I would blog my approach to making CorelDraw 11 do what I want in case the one other person who uses CorelDraw in this sort of configuration is interested :-).

For example, I usually draw all my LaTeX figures in one CorelDraw document and then use a bulk export macro to export each page as a different eps file that I can reference in LaTeX. CorelDraw 11 doesn't let you configure eps export options from a macro, so you have to export one eps file by hand first and configure the export options there, and then when you run the macro, it will just reuse the export options that you set before.

Also, pdflatex prefers to import vector graphics in the pdf format. Unfortunately, CorelDraw 11's pdf exporter doesn't support bounding boxes, so the exported pdf files do not import correctly. I found this program called eps2pdf (I use the one that comes with a nice Windows GUI because I can't figure out how to invoke the preferred eps to pdf conversion utility "epstopdf") that can take eps files exported from CorelDraw and converts them into pdf documents that can be imported into pdflatex. The program chokes if the Corel-exported eps files have text converted to curves or if the Corel-exported eps files are too large. It's possible to invoke eps2pdf from the command-line to convert all eps files in a single directory, which is useful.

Just recently, I've tried to import a lot of xfig-created eps files into CorelDraw 11. This sounds a little odd, because it doesn't make sense to create diagrams in xfig when you own a copy of CorelDraw. The reason I needed to do this was that I needed to generate a lot of complicated machine-generated Postscript diagrams. I don't understand Postscript, but xfig generates very clean, easy to understand Postscript output. So when I'm in this situation, I draw a couple of simple primitives in xfig, export it as eps, then write a program that follows the template generated by xfig in creating its own Postscript diagrams. Unfortunately, Corel's eps importer imports the text in xfig eps files as curves instead of as text. I managed to side-step this problem by using ps2ai.bat to convert the eps Postscript files into ai Postscript files. CorelDraw 11 then imports the text in these ai files without problem. Unfortunately, somewhere along this conversion process, extra outlines get added to objects. It's possible to simply delete these outlines by hand (especially easy if you use the ObjectManager view), or you can import the xfig eps files directly, copy all of the non-text objects, and then use these objects to replace the non-text objects in the imported ai files. There's probably an easier way to do this, but I'm still trying to figure it out.

Friday, February 04, 2005

Extensibility in X3D

During my rant against X3D yesterday, I wanted to complain about the extensibility model of X3D as well, but I couldn't think of a better approach to supporting extensibility in a 3d file format, so I decided that it would be inappropriate to make a big deal about it.

Of course, I thought up of a better scheme last night, so now I feel justified in complaining about the approach used by X3D to support language extensions. Although I complained about how the X3D event model was too abstract to usefully express certain concepts, I find that the X3D scene graph hierarchy to be too concrete and specific to support extensibility in a graceful manner.

In X3D, scene graph nodes are well-defined types. Each node has specific fields and no others. To add support for different objects, one has to create a new scene graph node with the fields one needs (or insert a lot of meta data, but I'll discuss that later). If an X3D browser encounters a node type that it doesn't understand in an X3D file, probably the best it can do is to simply ignore that node. Unfortunately, this doesn't degrade gracefully. So, for example, consider the mesh objects that are currently in X3D. If I want to make an articulated mesh, I need a way to add weights to each of the mesh vertices describing the influence of various bones on the position of the mesh point. To do this, I need to make a new scene graph node for articulated mesh objects that has a field for holding the bone weights. So now, if an X3D browser encounters my new articulated mesh node type in a file, it won't know what to do and will simply not render it. Ideally, the browser should simply degrade gracefully and render the data as a normal mesh, but it's not possible because there's no way for the browser to know that there's a link between an articulated mesh and a normal X3D mesh. Over time, as more and more node types are added to the standard, the standard becomes so big that no browser is able to implement the whole specification, resulting in many X3D files that are simply incompatible with many X3D viewers. In fact, this can already be seen in the current standard which has different node types for IndexedFaceSets, IndexedTriangleSets, IndexedTriangleFanSets, and IndexedTriangleStripSet. All of these node types are variations on the same theme, but an X3D browser must be explicitly coded to handle all four types separately.

One way around this problem is to use the metadata facilities of X3D. So an articulated mesh could be stored as a normal mesh with all the bone weights stored as metadata in the mesh. A browser that doesn't understand the metadata can just render the mesh as a normal mesh, and a more advanced browser can interpret the metadata and extract the bone weight information. Similarly, all the different triangle sets could be encoded as IndexedFaceSets with metadata suggesting the optimisation of rendering the node as triangles. And therein lies the way to gracefully supporting extensibility in X3D. There shouldn't be set node fields in X3D. Instead, all fields should be metadata. Most 3d objects can be described as a control surface with various extra descriptive data thrown in. As such, X3D should simply abstract all 3d objects to being a base control surface type, and all the extra descriptive data about normals, colours, and shape, etc. should just be metadata. So a cone is a box node that is tagged as a "cone" in its metadata. A height map is just a mesh node that is tagged as being a "height map" with some metadata describing the orientation of the heights. It may not be the most efficient way of storing data, but the benefits in terms of gracefully supporting extensibility is worth it. A minimal X3D browser then only needs to be aware of a small number of abstract node types. Even on very complex 3d models, an X3D browser will always be able to extract something that it can render.

Instead, X3D simply took the flawed VRML model and recoded it in XML. I guess we can always wait until X3D 2.0.

Thursday, February 03, 2005

U3D vs. X3D

I was looking at the website of the purveyor of the X3D format yesterday, and I noticed that they had a newspost slamming the rival 3D format U3D there. I haven't read the U3D spec yet, but based on the newspost, it sounds pretty good. In fact, I think that if the U3D spec had been available when I started my X3D project, I would have used U3D instead.

The newspost complains about how X3D only supports triangle meshes and the like. Honestly though, having just finished implementing a horrible n^4 concave polygon triangulation algorithm for my X3D viewer, I'm liking the idea of a format only supporting triangle meshes more and more.

I've only implemented a small amount of the X3D spec, and I can't help but feel that it lacks a certain elegance and simplicity in its design. I think many of the problems evolved out of the fact that the designers wanted people to be able to code X3D by hand. As such, the spec supports lots of shortcuts and features to aid people coding up X3D manually such as the ability to leave out certain tags or to let the browser automatically calculate normals etc. These sorts of things simply make the implementation more complicated and results in lots of "special cases" in the specification. In reality, no one designs a 3d model using text (believe me, I tried this once. It's totally hopeless), so it would have been better to leave out stuff like that.

I'm not implementing the X3D event model, so I'm not too familiar with it, but my gut feeling is that it is likely too expressive. The Postscript language has a similar problem in that it is a full programming language, meaning that extracting meaning from the language is extremely difficult without actually executing it. For example, let's say I wanted to export an animation to another program. The exported animation will have a clock object whose timing is fed into some sort of coordinate generator whose events would be fed into the actual object being animated or something like that. Would an X3D importer be able to interpret the combination of event objects and event routing as being an animation and to import it as such? Or would it simply have to import these event nodes as is and leave it to the user to figure out that it represents an animation? Just as human language is too expressive for computers to understand, which is why we have programming languages, the X3D model might be too expressive for an import tool to recognize the patterns, which is why more restrictive languages are often more useful. If a language is too expressive for an import tool to understand its meaning, resulting in it being imported as a black box, then the language might as well be some standard language like ECMAScript that people are already familiar with.

And of course, there's my bias against "platforms." I feel that the best specifications are for little self-contained toolkits that can be bolted on to existing applications. X3D was designed as a complete platform for 3D browsing, so it has a tendency to want to take over your application as opposed to being a simple bolt-in. For example, to implement a module for importing animation, you need to add the event model to your application, some sort of reflection mechanism for X3D objects to parse the event code, the actual X3D objects themselves, etc. etc. Afterwards, it's no longer a simple little import tool; you've essentially just written an X3D browser. At that point, you might as well just write your whole application to be X3D-based.

X3D simply tries to do too much and as a result is too complex. U3D focuses on one small aspect of 3D file exchange and hopefully ends up being small, graceful, and easy to use. It's somewhat like the TIFF file format which is so complicated and supports so many features that no one really uses it for anything. It's a coin toss as to whether an arbitrary TIFF file might be importable by a TIFF import tool or not: there might be multiple pages in there, encoded in some weird colour space, compressed using some unknown scheme, etc. With PNG, you're pretty much guaranteed success.

Saturday, January 22, 2005

JSR-184

After a break of a few weeks, I went back to X3D coding, and as a result, I now have a working X3D parser, and I've implemented just enough of the X3D spec that one can look at boxes and set a viewpoint.

I started to become a little worried after I noticed that I was approaching 6-7k of code just to draw a little box, so I decided to port what I had to J2ME to make sure everything worked. Good thing I started early because if I had left the port until the last moment, I surely would have had a seizure or something.

Apparently, vertices and normals are defined using bytes and shorts in JSR-184 (the current Java specification for doing 3-D graphics for cellphones). Yes, I am aware that cellphones do not have floating point units, making floating point math very slow, but bytes and shorts? This makes the porting of any graphics code from desktops to cellphones mind-numbingly difficult. Everything has to be torn out and carefully redesigned so that they work correctly with byte and short values for vertices. And such a design has a shelf-life of about two years because if 3-D graphics ever take off cellphones, floating-point units will be added to the devices, and developers will demand a new API with better floating-point support. Sure, I'm glad that Nokia is very proactive about defining new Java API standards for cellphones; otherwise, the latest cellphone features simply wouldn't be accessible from Java (or, at least, not in a standardized way). But I really do wish that Nokia would spend a little bit more time polishing their APIs before releasing them, so that the APIs wouldn't fall into obsolescence so quickly, necessitating the creation of yet another unpolished API to replace it, which'll become obsolete again in just a few years etc. etc.

Would it have really been so hard to allow vertices and normals to be defined using floating point values? Sure, it would be slow, but it would be nice to have that option at least. And adding that support would add another year or two to the life of the spec, at a minimum. I might expect this sort of lack of foresight from a bunch of amateur hacker coders, but I imagine that Nokia probably has some good people on this. I think it must be part of a larger corporate strategy of planned obsolescence in software. Because the old APIs are so limited and restrictive, developers will have to keep on moving on to newer APIs to make use of newer features. Since the new software is incompatible with older phones because the software makes use of the newer APIs, people have to upgrade their phones to use the newest software. And, if the new phones don't even bother to include the old APIs, then users can't just copy software from their old phone to their new phone; they have to buy all new software for each of their phones. This is good for the corporate establishment not only for the above reasons but also because it hinders piracy and allows vendors to control the availability of software on different platforms. All of this, of course, is meant to oppress the consumer and to wring as much profit as possible out of the pockets of the average worker, the elderly, and teenagers around the world.

Or, maybe Nokia just hired a bunch of amateur hacker coders.

JOGL and Resizing Windows Part 2

Yeah, apparently the problem I was having before was simply a driver problem. Of course, Intel hasn't updated their drivers in a while, so I guess I'll have to live with it.

Tuesday, December 14, 2004

JOGL and Resizing Windows

I'm not sure if I'm the only person who's not using JOGL to do animation, but I seem to have a problem where when I resize a JOGL window, it fails to update its screen correctly. Most people don't encounter this because if they constantly update their screen inside an animation loop, any update failures will correct themselves during the next pass through the animation loop. A quick search through Google brings up nothing.

What happens is that if I use the November 19th build of JOGL, when I resize the window, I get a blank white screen. When I resize it again, I get my image displayed correctly again.

I suspect that the problem has something to do with double-buffering after a resize. Here is my evidence:

a) when I do successive resizing, it alternates between being ok and not being ok
b) after I do a resize, cover the window, and uncover the window, the window looks fine again
c) if I create a single-buffered OpenGL context, JOGL keeps dumping stack traces to the console
d) The following bit of code looks suspicious:
if (autoSwapBuffers && !isReshape) {swapBuffers();}

Still, when I trace through the execution of the code, everything seems to trigger correctly, so I suspect that maybe I'm just doing something incorrectly in OpenGL or elsewhere. If I force an extra buffer swap after a reshape, everything does seem to work correctly (the white screen still shows, but it's quickly overwritten during the successive call to display). Perhaps it's a driver problem. I should try this on a different machine.

Sunday, December 12, 2004

X3D and the Importance of High Quality Specifications

This isn't a real post but more of a rant session about the quality of the X3D specification. This spec is of mediocre quality at best. It's quite clear that they revised the spec many times and forgot to clean up references to old revisions. For other parts of the spec, they seemed to be describing an existing implementation as opposed to specifying how new implementations should behave (i.e. they leave out important details). Various parts of the spec are inconsistent or confusing. Worst of all, some parts of the spec give off the impression that they've NEVER BEEN IMPLEMENTED.

I've only tried to implement a very small amount of the specification so far, but here are various problems I've seen so far:

1. A lot of the example interfaces for the Java language bindings are inconsistent with other parts of the specification or are simply wrong.

2. The Java language bindings have clearly never been implemented or tested.

3. Default values are defined for several field instances when they are simply the same as the defaults for fields themselves

4. They never really make it clear what their notation for node fields are

5. Various inherited fields are listed repeatedly over and over again

I suppose it's a little worse for me because I'm autogenerating code based on the specification, so things that would be glossed over by someone implementing the specification by hand really cause problems for me. Oh well. So far, I haven't hit any part of the spec that was so outrageously wrong that I couldn't figure out what they had intended, so maybe things aren't so bad after all.

Friday, December 10, 2004

X3D Ambitions

After spending more time trying to understand the X3D spec, I think I've decided that it is simultaneously less ambitious and more ambitious than I had expected. I had initially thought that X3D intended to define specifications for a lot of the annoying 3D programming issues like file exchange, scene graphs, etc. This way, programmers could just use some X3D components instead of having to code their own lower layer 3d code. Based on what I had read from the spec and about the history of X3D, I thought that that's what X3D was for. I'm a little skeptical of that idea, but it does sound intriguing. I'm actually a little disappointed that this isn't wasn't X3D was aiming to do. In fact, X3D seems to be just a standard for a 3d media player/browser. They've essentially designed a file format for X3D media and an API for talking with X3D browsers. If X3D were a database, the X3D specification would describe the file format of the database, an RPC framework for communicating with the database, and a general description of how the database should behave. This is an ambitious vision, but it isn't as generally useful as having a bunch of lower-level components. Hopefully when the 3D Industry Forum comes out with their competing spec, it'll be possible to compare which approach is more useful. I suppose that it's like the difference between white-box and black-box inheritance. Oh well.

In any case, generating code using XSLT seems to work pretty well. It's a little verbose, and you have to watch for those <> characters in the code, but I've been pretty satisfied so far. Hopefully, if all goes according to plan, I'll have a rudimentary partial implementation of a few nodes from the SAI layer of X3D by Monday. Then I can actually start cobbling together a renderer and parser.


Thursday, December 09, 2004

Starting with X3D

So, I somehow committed myself to making a simple X3D browser for mobile devices, but it's really hard to figure out where to start. I've been browsing the specification for several days now, and it's just not really sinking in. Usually, the reference implementation (xj3d) would be the normal place to start, but it's really a VRML browser with a thin veneer of X3D on top of it. In any case, most of xj3d seems to be hand-coded, but the specification looks really amenable to automatic generation, which is the route I want to take.

In order to code up a browser, you need a simple 3d engine first. Since X3D defines a scene graph API, it seems like that working on that API would be an ideal place to start (since one can use a scene graph as the base for a 3d engine), but the more I read about the X3D scene graph API, the more I realize that it's inappropriate for doing any sort of rendering from it. Plus, the interface for getting a browser instance seems cumbersome to code up as well. Still, I suppose it's as good a place to start as any.

For the code generator, I was originally thinking of coding something up in Java, but I think I might make an attempt at putting something together in XSLT. I'm not sure if it'll work, but it's always good to use existing standards, so I suppose it's worth a try. Of course, XSLT doesn't support generating multiple output documents from a single input document, so I'll still have to write some sort of coordinator or something.

I guess I'll start with something simple by auto-generating the exception classes. Already, there are some pecularities in the spec, because initially they define a bunch of abstract language-independent exceptions and then later in the spec, they decide that for the Java version, they'll use a different set of exceptions using a completely different naming scheme. This is actually sort of annoying; I think it's a bug in their spec.

Sunday, November 28, 2004

Understanding X3D

For the past few months, I've been trying to wrap my head around this whole X3D thing. I haven't really done anything with it yet, but I have read a lot of documentation, and it just isn't clicking with me.

I think the problem is that when most people decide to learn X3D, what they're looking for is a nice universal file format for 3d models. My impression is that to work with 3d models now, you have to go about downloading various SDKs describing how to work with certain propriety model formats that are outputted by programs that you could never afford. Developers want some sort of standard file format that they can work with instead, and ideally X3D would be this standard. What they actually get is VRML encoded in XML.

Now VRML sort of puttered out a few years back, and I suspect that this would probably explain the lukewarm reception of X3D right now. Most people that I've talked to have either never heard of X3D or simply don't care.

In any case, because of X3D's VRML past, it actually does three things:

FILE FORMAT

X3D describes a way of encoding 3d geometry in XML. This part of the specification is what people actually want X3D to do.

SCENE GRAPH

I think X3D also defines an API for storing and manipulating scene graphs in memory. In fact, the file format is simply a way of serializing the scene graph to a file. I'm a little ambivalent about this. Admittedly, every time anyone wants to do anything in graphics, they have to put together some sort of scene graph code. Each year, thousands of computer science students taking graphics course have to put together a new scene graph framework so that they can do some 3d work. And anytime a company decides to create a 3d API (e.g. Java3d or JSR184), they always decide to create their own scene graph API to go with it. So I suppose it would be nice if everyone could agree on a single scene graph API. On the other hand, the first thing that people ask upon encountering a scene graph API is "how do I make it show a bunch of triangles on the screen like in OpenGL," so maybe a standardized scene graph API isn't all that useful an abstraction. After all, you don't see people creating a bunch of objects for representing shapes and geometry of 2d scenes. I guess the thing that causes me the greatest concern is the fact that all the X3D implementations that I've looked at (which is, admittedly, only two) take the X3D scene graph and immediately convert it to a different scene graph format before doing anything with it. This includes the X3D reference implementation! If the scene graph API were any good, then there really shouldn't be any reason to convert it to a different representation, right?

PLATFORM

Because of its VRML roots, X3D similarly tries to provide a complete "platform" for doing 3d applications. In other words, X3D seems to provide enough language bindings, scripting support, interactivity features, event models, etc. that X3D can be used as the basis for a complete 3d application. Personally, I think this is the most dubious aspect of X3D because understanding and implementing all of these features is really hard, and people who are only interested in a universal 3d file format really don't care about this stuff. I think it may be possible to make a compliant X3D implementation that ignores all of the platform stuff, but I'm not entirely sure yet, and in any case, I find the X3D documentation extremely hard to read because of all the references to these platform features.

So I guess the primary question is whether X3D fails as a file format because it tries to do many other things as well. Frankly, I don't know. I have committed myself to doing some work with X3D though, so hopefully I'll be able to figure this out as I dig deeper into the specification.

Saturday, November 27, 2004

First Post

Well, I've been thinking of doing some blogging for a long time, but every time I was about to start, I kept getting this horrible feeling that my blog would simply end up being a summary of stuff I read on Slashdot.

I occasionally do some coding though, and sometimes, I hit a snag that I'm sure that someone else has encountered before, but I still have to spend hours and hours researching answers. Afterwards, I can't help but wish that other people had documented their experiences, so that I wouldn't have to waste hours redoing what they've already done.

So skipping right to the point, this blog will be a summary of various issues that I've encountered during coding and the solutions that I found worked.