Gleaming the Cube: displaying a 3-d box of perspective-transformed bitmaps using client-side web technologies?
April 19, 2006 3:11 AM   Subscribe

How would one create a web page showing a 3D rotating cube, with sides of the cube displaying arbitrary visitor-supplied images as their faces?

So, obviously this is a multi-step process: user visits site, user uploads up to six images, then user sees rotating cube. Getting users to visit isn't my responsibility, so I'm not worried about that, and uploading images is easy, so I'm not worried about that. Generating the rotating cube, on the other hand, is somewhat unfamiliar to me, so that's what I'm looking for help on.

My initial thought was to feed the visitor-uploaded images to a Flash movie, which would then smoothly execute a few perspective-transformation tweens on them, creating the cube illusion, right? However, the somewhat experienced Flash developer on my team showed me that Flash won't do perspective transformations (or even stuff like skew, transpose, and rotate) on bitmaps -- it simply treats bitmaps like a special fill-pattern on a polygon, and transforms only the border. This seems like a serious limitation to me, and I'm surpsised that Flash has it, but we can't find a way around it at the moment. Can someone prove us wrong and point us to a working method?

(In fact, curiously enough, tools or code libraries that perform transformations on raster images in general seem to be thinner on the ground than I would have thought. I was thinking there'd be all kinds of free libraries that did everything from rotations/translations to crazy conformal mappings, when in reality I'm having trouble finding much that does something beyond shrinking or cropping or some work in the colorspace.)

We also looked at using a 3D tool (Swift3D) to accomplish the job, but it didn't seem to allow for us to pass arbitrary images adorn the sides of the final rendered cube. And I'm not sure that it's outputting anything more sophisticated than outputting the swf equivalent of an animated gif.

If Flash really can't do this, I'm considering:

(1) Java applets. Never been a huge fan of them, but if I recall correctly, the Java 2D API has facilities for doing affine transformations on raster images. Heck, maybe even some super spiffy 3D API that'd make this easy (anybody know?)

(2) Now with more AJAX! I could always write some unholy mess that generates a series of frames for the cube in various states of rotation on the server side, and some javascript that dispays them on the client side. However, this option makes Java applets start to sound sensible.

(3) SVG? VML? VRML? I don't know much about any of those, so I'm just sortof hoping a passing MeFite might know these well enough to comment on whether or not they have any suitability for this task. Preferably more than #2.

(4) Are there better 3D tools than Swift3D that could let us script the behavior of the cube and parametrize the images displayed on its side, and deliver in Flash? If perspective transformations on bitmaps are truly impossible, then I suspect this doesn't exist, but one can hope...

(5) Anything else people want to suggest. Up to and including "don't do it" (though the client has convinced me the visual would in fact really help in selling his product).

Finally... any general pointers to resources about transformations on raster images or otherwise using raster images in a 3d context are welcome!
posted by weston to Computers & Internet (26 answers total)
 
Java actually has a 3D library, but it's probably overkill for this sort of application. You could probably get away with using double-buffering and the AWT package. This should get you started. :)
posted by Civil_Disobedient at 3:35 AM on April 19, 2006


You could use Macromedia Fireworks for the image-transformation, then use flash to display the final results. I've used Fireworks in this sort of capacity before - as part of customized CMS installations, whereby Fireworks was used to generate custom images and manipulate uploaded images.
posted by syzygy at 3:38 AM on April 19, 2006


For purposes of clarification, you could use Macromedia Fireworks to automatically manipulate the uploaded images (as opposed to having someone do the work manually). Fireworks has excellent scripting support.

The way we used it was via a scheduled task on the server. This scheduled task called a script that searched for newly-generated Fireworks scripts in a pre-determined directory. If Fireworks scripts were found, they were run (performing the required image manipulation[s]), then deleted / archived.

These Fireworks scripts were generated during the image-upload process, so every time a user added new images, a new, server-side Fireworks script was generated.
posted by syzygy at 3:45 AM on April 19, 2006


My apologies that the above package doesn't contain any transformation goodies. Looking deeper at the 3D API, I have to say it's a pretty powerful package. For instance, here is the code for a rotating cube:

public class HelloJava3Da extends Applet {
  public HelloJava3Da() {
    setLayout(new BorderLayout());
    Canvas3D canvas3D = new Canvas3D(null);
    add("Center", canvas3D);
    BranchGroup scene = createSceneGraph();
    SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
simpleU.getViewingPlatform().setNominalViewingTransform();
    simpleU.addBranchGraph(scene);
  }

  public BranchGroup createSceneGraph() {
    BranchGroup objRoot = new BranchGroup();
    objRoot.addChild(new ColorCube(0.4));
    return objRoot;
  }

  public static void main(String[] args) {
    Frame frame = new MainFrame(new HelloJava3Da(), 256, 256);
  }
}

Plus, the API has built-in methods for bitmap transformations. Here is a cube with transformations applied to the surface texture. I haven't done any Java graphics coding since the 90's, but I have to admit the 3D API really makes things look easy! Good luck...
posted by Civil_Disobedient at 3:50 AM on April 19, 2006


Your developer is wrong, Flash can happily rotate and skew bitmaps, it's just the perspective stuff that gets tricky. You can do a decent rotating cube without true perspective though, e.g. I found this example with a quick Google search.

It just reminds me of tacky 80s TV transitions, so unless the product involves cubes I'd think of something more interesting/impressive/relevant.
posted by malevolent at 3:52 AM on April 19, 2006


I think you'd probably be happier with a 'real' 3d solution. Figuring out all the perspective and stuff for a 2d cube that isn't really rotating is difficult. And if you don't get it exactly right the first time, and the designer wants it from a different angle, you have to do it all again.

If you use a 3D package, it's all done for you, and usually hardware-accelerated to boot.

Essentially, all you're doing is creating a 3d cube (trivial), assigning a different texture to each face (trivial in any kind of decent package), and then spinning the cube(should be trivial, although rotations in 3d can be tricky.)

For extra points, you could even let the user rotate the cube with the mouse. That would be easy with a 3D package, and damn difficult with a precomputed 2D translation. You'd end up manually doing the 3D transforms that the library would just handle for you.

Seems like Java is tailor-made for this approach... rich libraries, and the program doesn't actually have to do much work.
posted by Malor at 4:15 AM on April 19, 2006


(I should note: I have not done this... this is a 50,000 foot overview. But I've seen it done, and I really don't think it's hard. )
posted by Malor at 4:16 AM on April 19, 2006


That cube looks very strange without perspective to me, malevolent.
posted by musicinmybrain at 5:09 AM on April 19, 2006


You could use the Sandy .2 3d API for flash. It'll do exactly what you're looking for.

http://sandy.media-box.net/blog/index.php
posted by Lord_Pall at 5:14 AM on April 19, 2006


Java 3d isn't a standard part of the java distribution, so you won't be able to do java 3d. You certainly can do all the 2d image manipulation you want, direct image manipulation at the byte level. There are also API functions for rotating and transforming stuff.

Java3d isn't really being actively developed anymore, either.
posted by delmoi at 5:17 AM on April 19, 2006


Flash also has a framebuffer system you can use to draw arbitrary bitmaps now. That looks like what the sandy system is using.
posted by delmoi at 5:19 AM on April 19, 2006


Actually, I'll retract my suggestion. After a little extra thought, I feel that it's not the best way to achieve what you're looking for - was a little quick on the trigger finger.

Unfortunately, I don't have a better suggestion. Good luck!
posted by syzygy at 5:23 AM on April 19, 2006


I can't believe no one has mentioned Director!
posted by jedrek at 5:38 AM on April 19, 2006


the processing Java library set has a phenomenal amout of tools to facilitate just this sort of thing. It's designed to create user-interaction based environments, and it just seems like an ideal match for your specs (but in java).
posted by potch at 6:36 AM on April 19, 2006


to be more exact, take a look at this demo and set the color data points along some vertex grids for each face. so, read out each pixel's color, and make it a vertex along that face's surface. Processing does the gradient heavy lifting for you, which will create the desired effect.
posted by potch at 6:43 AM on April 19, 2006


What's wrong with the cube malevolent pointed to? It looks exactly like the solution I imagined when I read the question.
posted by jjg at 6:51 AM on April 19, 2006


I've gotta say, Sandy looks very attractive as well.
posted by potch at 7:05 AM on April 19, 2006


On a fourth note, it's a heckuva lot easier to do the image face in Processing than I initially described. You just use the texture() function and specify the image data. That seems pretty awesome to me.
posted by potch at 7:54 AM on April 19, 2006


Java applets can now use the OpenGL bindings (jogl) without any installation of software (apart from the Java VM): JoGL Applet Test.

I'm not sure what would be better for a simple cube though... - A 3D api such as OpenGL or using a 2D api to draw and rotating the corners of a cube (to get the polygon the image have to be transformed to fit) manually (my first Java applet almost 10 years ago was a rotating 3D cube, with correct perspective :))

As flash is more widespread than java vms a flash solution would probably be best though.
posted by rpn at 7:57 AM on April 19, 2006


As above: Flash 8 lets you do pixel graphics, but not 3D natively AFAIK. Java, Director and Processing do 3D natively, so you don't have to worry about the details of the 3D-2D transforms. Careful with Java in 3D - not all libraries are crossplatform.
posted by cogat at 3:19 PM on April 19, 2006


Response by poster: I've wanted an excuse to play with Processing for months, and this could be it. The only reservation I have is browser penetration for Java.... does anyone know if this is likely to be problematic when it comes to using Processing?
posted by weston at 4:22 PM on April 19, 2006


All ie w/java and firefox on pc seem to be okay. I cobbled together an example. If you look at the source, you can see the urls i called. I you were to doan upload option, you could call those urls as php files that fed you the images(a la "www.smoo.com/getsideimage.php?s=2", assuming you stored the user's uploaded images in a unique directory or database or some sort of data storage jiggery pokery.)
posted by potch at 6:57 PM on April 19, 2006


Response by poster: potch, your pointers have been so many kinds of awesome already that I hate to even ask any more questions, but I'm wondering if you know two things:

(1) I can see in your example that you've grabbed several different images, but it looks to me like only s1 is getting used as the face of a cube. Is that correct? If so, do you know why it's happening?

(2) It's obvious Processing can be used to create the effect I need. In order to merge the effect into the application, though, I'm going to need to somehow tell Processing about session information that will help it not only locate arbitrary images, but the specific arbitrary images a given user uploads. Do you know if I get the environment an applet would normally run in (and therefore the information an applet would usually have access to) for free in the context of the processing code I write? Or some other way to get session info in?

This is really cool stuff. I'm glad I asked this question.
posted by weston at 8:06 PM on April 19, 2006


Westion: No problem, I love a challenge :)

1)I'm presumably working on it. It was a situation where for each cube face, you need to create a beginShape() endShape() pair. I also found that some of the transparent pngs can cause problems. If you stick with jpg files, or avoiding semitransparent pngs, you should be alright.

2) To get information from a session, I would call a php script in the loadImage() url that pulls session image data in.
posted by potch at 10:31 PM on April 19, 2006


westion meets question, apparently.
posted by potch at 10:33 PM on April 19, 2006


Do you mean something like this

- turn on your iSight or webcam by pressing the space bar

- control the cube with your hands

It is hilarious to show people on my MBP!
posted by KimG at 12:17 PM on April 22, 2006


« Older Save my suede handbag!   |   Televised European soccer in NYC. Newer »
This thread is closed to new comments.