Archives for February 2008

Java3DBuilder – Textures and Lighting

I was hacking a little bit on Java3DBuilder when I was trying to kill time in VA the day before Groovy/Grails Experience. Textures and lighting are the fruit of that labor. I’m still figuring out some of the details of having lighting affect textures(TextureAttributes class) but basic texturing works and provided there are normals present, lighting works.

 

For a cube with texturing normals, the following code is how to add a texture to that cube:
appearance {
    texture2D(image: new File("images/test.png"), magFilter: Texture.BASE_LEVEL_LINEAR,
 minFilter: Texture.BASE_LEVEL_LINEAR)

}
That call replaces the following code:

 

def file = map.remove("image")
             def loader = new TextureLoader(file.toURL(), TextureLoader.ALLOW_NON_POWER_OF_TWO, null)
             def image = loader.getImage()
             texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, image.getWidth(), image.getHeight())
             texture.setImage(0, image)
 ...
 //call all the setters

In the lighting example, we draw a sphere and a cone, each with a directional light to the side of it. There is a bit of convergence of the the light sources on the surface of the sphere.

 

 

Here’s the important code that’s at work.

 

transformGroup(translation: new Vector3f(3.0f, 0.0f, -2.0f), capability: TransformGroup.ALLOW_TRANSFORM_WRITE) {
                    sphere() {
                         appearance {
                             material()
                         }
                     }
                   directionalLight(influencingBounds: new BoundingSphere(new Point3d(-5.0d,0.0d,0.0d), 4), color:new Color3f(1.0f, 1.0f, 0.0f))
                 }
                 transformGroup(translation: new Vector3f(0.0f, 0.0f, -2.0f), capability: TransformGroup.ALLOW_TRANSFORM_WRITE) {
                    cone() {
                         appearance {
                             material()
                         }
                     }
                   directionalLight(influencingBounds: new BoundingSphere(new Point3d(5.0d,0.0d,0.0d), 4), color:new Color3f(0.0f, 1.0f, 0.0f))
                 }

 

2G Experience, Day Three

Day three has been much more chill and laid-back. I am somewhat disappointed to only have have found a Chili’s next to the hotel with much cheaper drinks last night.

Alex’s (Popescu) talk really delved in regular SQL. It went really in depth to the models and solutions offered by Groovy. Though mapping to Hibernate is not difficult at all, I’ll probably continue to use groovy.sql.Sql in my one-off export and update scripts.

I had a quick chat with Glen about my Google Chart plugin before his talk on Extreme Grails UI Makeover. Great guy. Someone mentioned that they wonder why we (Americans) always get foreign guys do extreme UI makeovers. I think it’s because we like listening to the accents and the potential for double entendres. I would have to say Glen’s talk was one of the most entertaining.

Jason Rudolph’s Refactotum was plagued by the not-so great (awful) bandwidth at the hotel. Despite that, the bits that I saw were good.

There will be another 2GX in early October, forgot the exact dates, in San Jose, CA. There is also a more focused 3-day bootcamp in Denver that will be taught by Scott Davis. 2GX is worth the cost, think of it as a big buffet that you can walk up and down and sample all the offerings or really get to know the stuff in the dessert section.

 

2G Experience, Day Two

Graeme’s talk on Empowering Spring with Groovy DSLs, although mostly targeted toward the Spring BeansBuilder, provided lots of insight into EMC and MOP.

I also attended Andres’ talk which unfortunately was scheduled in the same slot as several Grails talks so all interested parties might not have been able to attend. The code is available now:

http://svn.codehaus.org/groovy-contrib/junctions/trunk

Warning, it is a work in progress but what’s there works. Andres and I built the domain model based upon the REST tutorials in the grails online documentation(http://grails.org/doc/1.0.x/guide/13.%20Web%20Services.html#13.1%20REST).
The main reasons for using REST are:

      1. It is easy to wire up and get running, and
      2. XmlSlurper and XmlParser

I did look into other transmission types like XFire, SOAP, and XML-RPC but a REST-like service was the easiest path. The client side is a combination of the various builders and components from SwingXBuilder, JideBuilder, and ObjectGraphBuilder and also uses Glazed Lists.

2G Experience, Day One

21 Feb - 14:51 EST - Right now, I’m waiting for Neal Ford’s preso on Design Patterns in Groovy to begin. Scott Davis gave the keynote and among the highlights is the fact that Groovy is now 31 on the TIOBE. Many well wishes were sent out to Guillaume Laforge who couldn’t be here due to impeding child birth.

I’ll be trying to post photos on flickr throughout the day under the tag "2gx". Stay tuned.

 14:59 - Design Patterns in Groovy room is packed.

15:50 - Neal has gone through some of the more popular patterns from the Gang of Four book and has shown how they are built into Groovy or easily implemented.

"...the title should have been ’how to make C++ suck less.’ " [Gang of Four book]

"It’s not that they are statically typed that they are bad, it’s the amount of ceremony you have to go through to get something done(essense)". - on how the argument isn’t static vs. dynamic, it’s ceremony vs. essense.

 Really good preso, gave some good insight on how to implement AOP features in Groovy.

16:47 - A little downtime, scoping out my seat for Graeme’s talk on plugins.

19:23 - Grubbin. Went to Graeme’s talk, a good evolution of the plugin talk from Grails Exchange...lots of new content and somewhat of a teaser for his talk tomorrow on Spring and Hibernate. I’m liking the thought of a Grails platform (Grails - the web bits). Maybe that idea can be expanded more in the space of a Grails/Swing mashup (shameless plug - I helped Andres with the app code for his preso tomorrow). Added a couple pics on Flickr.

22:10 - Hotel bar waxing philosophical on Flex, Swing and the like.

12:30 - Bit of a midnight code session. Hacked a bit on hCardBuilder.

01:22 - Time for bed.

More on microformats

Having arrived early to the DC area for 2GX and in need of a little time to acclimate to the temperature change, I chilled out in the hotel. As a Marylander, I can deal with cold but swings of more than 20 - 30 degrees throws my body off if I don’t take it easy the first day. It’s ironic that while I write this, a VisitFlorida ad appeared on TV. But I digress...

I recently blogged about Google’s Social Graph API and microformats. While perusing the microformats.org site one day, I came across a Java hCard builder/parser. hCard is a semantic (X)HTML representation of vCard information. It is used as an element in other types(hResume, hReview, hAtom) often to indicate ownership. I wanted to be able to make hCards but in a more Groovy way. Reinier Zwitserloot wrote classes for most of the compound components of hCard such as name, telephone, geolocation, etc so wiring them into a builder wasn’t that hard. I did have to make a custom version of the HCard container class(named hCard) to allow incremental building of the hCard. All I did was making the lists not be immutable and rewriting the for loops in the toString() and toHTML() functions. The linked version has all the basics defined (name, tel, geolocation, organization, address, and email). The more optional fields such as notes, nicknames, photos, logos, and the like will be in the next update.

With the builder, I can take the following code for a hypothetical worker at the 2GX hotel:

def hCard = new hCardBuilder()
         def card = hCard.hcard {
             n(givenName: ’James’, familyName:’Williams’)
             tel(number:’703-555-9000 ext 555’, types:[’WORK’])
             org(name:’Sheraton Resorts’, unit:’IT’)
             email(address:’name@email.com’,types:[’pref’])
             adr(streetAddress:’11810 Sunrise Valley Drive’, locality:’Reston’, region:’VA’, postalCode:’20191’, countryName:’USA’)
         }

and create the following hCard:

<div class="vcard">Contact information for <span class="fn">James Williams </span><br/>Proper Name:
    <div class="n"><span class="given-name">James</span> <span class="family-name">Williams</span></div>
    <div class="tel"> Tel [<span class="type">WORK</span>]: <span class="value">703-555-9000 ext 555</span></div>
    <div class="email"> Email [<span class="type">pref</span>]: <a href="mailto:name@email.com" class="value">name@email.com</a>
    </div>
    <div class="adr"> Address:<br/><span class="street-address">11810 Sunrise Valley Drive</span><br/><span
            class="locality">Reston</span>, <span class="region">VA</span>, <span
            class="postal-code">20191</span><br/><span class="country-name">USA</span></div>
    <div class="org">Organization: <span class="organization-name">Sheraton Resorts</span> [<span
            class="organization-unit">IT</span>]
    </div>
</div>

 

Simplistic, yes, but cool for an afternoon project and a needed component for more complex types like hAtom.

 

 

org.microformats.hCard - Java

hCardBuilder

The Firefox Operator plugin will identify microformats in web pages and allow you to export that information to an address book or scheduler, find it with Google or Yahoo maps, and other cool stuff.

Google Social Graph API and Microformats

Google recently released the Social Graph API which allows a user to see what sites are connected and the significance of those connections. Before you say this is a ploy by Google to own all your information, it isn’t...well not totally. At the core of the Social Graph API is XFN (XHTML Friends Network) and FOAF (Friend of a Friend). For XFN, on outgoing links, you use the rel attribute to indicate your relationship to the person (from acquiantance to colleague to crush/muse). FOAF uses a XML file to describe both yourself and your relationships to others. Once more folks have their pages tagged, you could use the API to construct connection lists like LinkedIn does.

To each link of an acquaintance, all you need to do is add a rel attribute. For example, to mark up a link for my friend RJ, I would change it to the following:

<a href="http://cplusstudent.com" rel="friend met colleague">RJ Salicco</a>

The full list of acceptable values are here.

Microformats(like XFN and FOAF) make it easier for humans and machines to parse information. So in that end, it does fit into Google’s mission statement.

Groovy coming to Ubuntu Hardy Heron

Though I wish I could say it was totally my doing, the only part I had in the process was submitting a sync request for a package that caused Groovy to FTBFS ("Fail to Build From Source"). I checked the bug today and found it was cross-linked with Bug# 185016, a resolved bug requesting a sync of Groovy from debian unstable.

Ubuntu 8.04 (Hardy Heron), as a LTS("Long Term Support") release, will be supported on the desktop for three years and on servers for five. In my experience, though there are a lot that upgrade every six months when a new release comes out, some are more conservative and only upgrade for LTSes. That makes it very easy for folks to make and distribute smaller widgets and apps on Ubuntu like they do with Python.

 

Java3DBuilder take two

As I recently blogged, I’ve been getting more interested lately in Java3D and have started making a Groovy Java3DBuilder. Existing for as long as I can remember, the OpenGL tutorials at GameDev (http://nehe.gamedev.net) are, IMHO, the true path from journeyman to master in computer graphics. Okay, maybe that sounds a bit too authoritarian. Nonetheless, they have some really good stuff. Those tutorials are what I am using to test the builder modifying and adding things along the way. It is feature-complete for whatever lessons are being covered but might differ in node name or implementation from the original.

The first block of lessons(1-5) center around the basics. In Lesson 02, we draw some colorless geometry. Lesson 03 and 04 add color and rotation while lesson 05 makes the shapes three-dimensional.

Lesson 03
You can thank Andres for the idea for the spiffy looking point nodes. Behind the scenes, the actual values of the attributes controls whether it generates a Point3f, Point2i, etc.
Lesson 03: Adding Color

This code builds the above image:

def su = j3d.simpleUniverse(canvas: canvas3D) {
            branchGroup {
                shape3D {
                    triangleArray(numVertices: 3, format: GeometryArray.COORDINATES | GeometryArray.COLOR_3) {
                        vertices {
                            point(x: 0.0f, y: 1.0f, z: 0.0f)
                            point(x: -1.0f, y: -1.0f, z: 0.0f)
                            point(x: 1.0f, y: -1.0f, z: 0.0f)
                        }
                        colors {
                            color(r: 1.0f, g: 0.0f, b: 0.0f)
                            color(r: 0.0f, g: 1.0f, b: 0.0f)
                            color(r: 0.0f, g: 0.0f, b: 1.0f)
                        }
                    }
                }
                transformGroup(translation: new Vector3f(3.0f, 0.0f, 0.0f)) {
                    shape3D {
                        quadArray(numVertices: 4, format: GeometryArray.COORDINATES | GeometryArray.COLOR_3) {
                            vertices {
                                point(x: -1.0f, y: -1.0f, z: 0.0f)
                                point(x: 1.0f, y: -1.0f, z: 0.0f)
                                point(x: 1.0f, y: 1.0f, z: 0.0f)
                                point(x: -1.0f, y: 1.0f, z: 0.0f)
                            }
                            colors {
                                color(r: 0.5f, g: 0.5f, b: 1.0f)
                                color(r: 0.5f, g: 0.5f, b: 1.0f)
                                color(r: 0.5f, g: 0.5f, b: 1.0f)
                            }
                        }
                    }
                }

            }
            viewTransformGroup(translation: new Vector3f(1.5f, 0.0f, 6.5f))
        }

Lesson 05
One major departure was the decision to not use the built-in timers to control animation. I instead used the TimingFramework to control animation and transitions. The Timing Framework is robust and provides a lot of features. It makes sense to use a consistent timing protocol throughout the project. On the other hand, this makes animation a little more difficult to specify in the builder.

Here the bit of Timing Framework code that makes the animation run:
public void timingEvent(float fraction) {
        rtri += 0.1f
        rquad -= 0.1f
        def q = j3d.transformGroup(rotX:rquad, rotZ:rquad, translation:new Vector3f(3.0f, 0.0f, -2.0f))
        def quadTrans = new Transform3D()
        q.getTransform(quadTrans)

        def triTrans = new Transform3D()
        triTrans.rotY(rtri)

        transform2.setTransform(quadTrans)
        transform.setTransform(triTrans)
    }

To test this out, in addition to a Java3D installation, you will need to include the location of the platform specific library files on the java classpath. Disclaimer: WIP, things might change.

Nehe Lessons 01-05

Current Java3DBuilder source

 

JavaFX to cannabilize Java3D

Sun recently announced that Java3D in its current state would be shelved for an upcoming JavaFX-minded 3D scene graph version. My question is whether the supposedly coming JavaFX train will make stagnating an API worth it. Despite the full court press blitz, JavaFX adoption seems to be tepid and kinda nichey. Halting new features on an API isn’t the way to build a community around it. I think whatever benefits from tailoring to JavaFX would already be present in a Groovy version.

Before the news I had started reading Pro Java 6 3D Game Development (which uses Java3D alot) and was planning to build on the Java3DBuilder that Luis Diego Fallas started. I’m probably going to still do that. At least I won’t be coding against a moving target.

I like jME and would move to it when the need arises but I think you learn more when you assemble the components that when you have a prepackaged product.

Groovy talks at JavaOne 2008

JavaOne notifications came out today as indicated by all the buzzing around the "Internets" by people saying what they got and didn’t get.

The bad news is that the technical session I submitted was rejected. But my two Birds of a Feather sessions (with my compatriots from the Groovy Swing team, Danno Ferrin and Andres Almiray) did get the green light.

Definitely an awesome way to end a work week.