Thursday, November 05, 2009

Smalltalk Sophie XUL in 3D for Croquet / Krestianstvo space description - разметка пространства в 3D

In this post I want to show, how the Sophie's 1.x (the true project, based on Smalltalk and not Java's one) XUL 2D logic for describing Tweak interfaces, could be used for describing 3D content of the Croquet spaces naturally.
Now it is included in Krestianstvo SDK, as XUL 3D feature.
To try out and to extend for the concrete needs, check for the recent updates from the SDK.

1. So, one could describe the content in plain XML file/string, like:
КрестьянствоБиблиотека class>>примерXUL3DSpacexml

^'<?xml version="1.0"?>
<space name="mySpace">
<imageWindow name="one" src ="checker.png" x="-10" y="0" z="-5"/>
<imageWindow name="two" src ="checker.png" x="10" y="0" z="-5"/>
<imageWindow name="three" src ="checker.png" x="-10" y="0" z="-5"/>
<space name="mySpaceA">
<imageWindow name="some" src ="checker.png" x="-10" y="0" z="-5"/>
<imageWindow name="other" src ="checker.png" x="10" y="0" z="-5"/>
<!-- ..etc... -->
2. Then this file is parsed into the real objects, node by node:
Крестьянство3DXulЗагрузчик>>readXmlFrom: xmlNode

|tframeClass tframe|

tframeClass := self croquetFrames at: xmlNode name ifAbsent:[nil].
tframeClass ifNotNil:[tframe := tframeClass new readXmlFrom: xmlNode in: self.].

3. Every XML node is parsed according to the methods defined in Крестьянство3DXulЗагрузчик class, for example 'imageWindow' is parsed as TWindow instance:
Крестьянство3DXulЗагрузчик>>readWindowFrame: aFrame from: xmlNode

| attr pic p attrX attrY attrZ matNorm |

(attr := xmlNode attributeAt: 'name') ifNotNil:[
nodeAttributes remove:'name'.
aFrame objectName: attr asSymbol.

(attr := xmlNode attributeAt: 'src') ifNotNil:[
nodeAttributes remove:'src'.

p := TRectangle new.
aFrame contents: p.

(attr asString) ifNotNil:[
pic := TTexture new.
pic initializeWithFileName: (attr asString)
mipmap: true
shrinkFit: false.
p texture: pic.
aFrame extent: pic extent.].
matNorm := TMaterial new.
matNorm ambientColor: #(0.8 0.8 0.8 0.8).
matNorm diffuseColor: #(0.8 0.8 0.8 0.8).
aFrame rectFront material: matNorm.

4. In TWindow class (or any other needed TFrame subclass) we add the method, which points to the method to parse the XML node with:
TWindow>>readFrame3DSpecificFrom: xmlNode in: uiLoader

super readFrame3DSpecificFrom: xmlNode in: uiLoader.
uiLoader readWindowFrame: self from: xmlNode
5. All, recognizable names of XML tags are defined in :
Крестьянство3DXulЗагрузчик class>>croquetFrames

^Dictionary newFrom:
#imageWindow ->TWindow.
#space ->TSpace.
#window -> TWindow.
#portal -> TPortal;
"any other stuff"
6. Finally, the created instances are serialized on to the shared island:
КрестьянствоОснова>>addTFToSpace: aFrame space: aSpace

| frameData tframe |

frameData := TIslandCopier new export: aFrame.
tframe := TIslandCopier new import: frameData to: self activeIsland.
tframe := aFrame copyOntoIsland: self activeIsland.

tframe future registerGlobal: aFrame objectName.
aSpace future addChild: tframe.
..and appeared in the World for collaborative interaction..

As a note: the Tweak menu bar on the top of the Participant window is described using the native Sophie's XUL 2D logic also.