r3632 - trunk/tools/ImgToMap/src/imgtomap
savagex at icculus.org
savagex at icculus.org
Sun May 18 06:08:18 EDT 2008
Author: savagex
Date: 2008-05-18 06:08:14 -0400 (Sun, 18 May 2008)
New Revision: 3632
Modified:
trunk/tools/ImgToMap/src/imgtomap/JFrameMain.form
trunk/tools/ImgToMap/src/imgtomap/JFrameMain.java
trunk/tools/ImgToMap/src/imgtomap/Main.java
trunk/tools/ImgToMap/src/imgtomap/MapWriter.java
Log:
evaluate alpha channels (can be used to punch "holes" into the generated terrain for maps with "organic" shape)
use platform Look&Feel (nobody likes Swing's Metal theme)
Modified: trunk/tools/ImgToMap/src/imgtomap/JFrameMain.form
===================================================================
--- trunk/tools/ImgToMap/src/imgtomap/JFrameMain.form 2008-05-18 09:43:40 UTC (rev 3631)
+++ trunk/tools/ImgToMap/src/imgtomap/JFrameMain.form 2008-05-18 10:08:14 UTC (rev 3632)
@@ -52,19 +52,19 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
- <Group type="102" alignment="0" attributes="0">
+ <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
- <Component id="jTextFieldTexture" alignment="0" pref="421" max="32767" attributes="0"/>
+ <Component id="jTextFieldTexture" alignment="0" pref="465" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
- <Component id="jTextFieldInput" pref="291" max="32767" attributes="1"/>
- <Component id="jTextFieldOutput" alignment="1" pref="291" max="32767" attributes="1"/>
+ <Component id="jTextFieldInput" pref="313" max="32767" attributes="1"/>
+ <Component id="jTextFieldOutput" alignment="1" pref="313" max="32767" attributes="1"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
- <Component id="jButtonOutput" pref="124" max="32767" attributes="2"/>
- <Component id="jButtonInput" pref="124" max="32767" attributes="2"/>
+ <Component id="jButtonOutput" pref="146" max="32767" attributes="2"/>
+ <Component id="jButtonInput" pref="146" max="32767" attributes="2"/>
</Group>
</Group>
<Component id="jButtonOK" alignment="0" min="-2" max="-2" attributes="0"/>
@@ -78,12 +78,18 @@
<Group type="102" alignment="0" attributes="0">
<Component id="jSpinnerHeight" min="-2" max="-2" attributes="1"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
- <Component id="jCheckBoxDetail" min="-2" max="-2" attributes="0"/>
+ <Component id="jSpinner1" min="-2" max="-2" attributes="0"/>
</Group>
- <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+ <Group type="102" alignment="0" attributes="0">
+ <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+ <EmptySpace type="separate" max="-2" attributes="0"/>
+ <Component id="jLabel4" min="-2" max="-2" attributes="0"/>
+ </Group>
</Group>
+ <EmptySpace min="-2" pref="132" max="-2" attributes="0"/>
</Group>
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
+ <Component id="jCheckBoxDetail" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -106,18 +112,21 @@
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+ <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jSpinnerUnits" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSpinnerHeight" alignment="3" min="-2" max="-2" attributes="0"/>
- <Component id="jCheckBoxDetail" alignment="3" min="-2" max="-2" attributes="0"/>
+ <Component id="jSpinner1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jTextFieldTexture" min="-2" max="-2" attributes="0"/>
- <EmptySpace pref="39" max="32767" attributes="0"/>
+ <EmptySpace type="unrelated" max="-2" attributes="0"/>
+ <Component id="jCheckBoxDetail" min="-2" max="-2" attributes="0"/>
+ <EmptySpace pref="18" max="32767" attributes="0"/>
<Component id="jButtonOK" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -126,12 +135,6 @@
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="jTextFieldInput">
- <Properties>
- <Property name="text" type="java.lang.String" value="/home/maik/netbeans/ImgToMap/test1.png"/>
- </Properties>
- <Events>
- <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jTextFieldInputActionPerformed"/>
- </Events>
</Component>
<Component class="javax.swing.JButton" name="jButtonInput">
<Properties>
@@ -142,9 +145,6 @@
</Events>
</Component>
<Component class="javax.swing.JTextField" name="jTextFieldOutput">
- <Properties>
- <Property name="text" type="java.lang.String" value="/tmp/test.map"/>
- </Properties>
</Component>
<Component class="javax.swing.JButton" name="jButtonOutput">
<Properties>
@@ -199,6 +199,18 @@
<Property name="text" type="java.lang.String" value="make detail"/>
</Properties>
</Component>
+ <Component class="javax.swing.JLabel" name="jLabel4">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Texture scale:"/>
+ </Properties>
+ </Component>
+ <Component class="javax.swing.JSpinner" name="jSpinner1">
+ <Properties>
+ <Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
+ <SpinnerModel initial="0.5" maximum="16.0" minimum="0.25" numberType="java.lang.Double" stepSize="0.25" type="number"/>
+ </Property>
+ </Properties>
+ </Component>
</SubComponents>
</Container>
</SubComponents>
Modified: trunk/tools/ImgToMap/src/imgtomap/JFrameMain.java
===================================================================
--- trunk/tools/ImgToMap/src/imgtomap/JFrameMain.java 2008-05-18 09:43:40 UTC (rev 3631)
+++ trunk/tools/ImgToMap/src/imgtomap/JFrameMain.java 2008-05-18 10:08:14 UTC (rev 3632)
@@ -18,6 +18,14 @@
/** Creates new form JFrameMain */
public JFrameMain() {
initComponents();
+ String testinput = "/mnt/data/nexuizsvn/nexuiz/trunk/tools/ImgToMap/test1.png";
+ String testoutput = "/tmp/test.map";
+
+ if(new File(testinput).exists()) {
+ jTextFieldInput.setText(testinput);
+ jTextFieldOutput.setText(testoutput);
+ }
+
}
/** This method is called from within the constructor to
@@ -42,19 +50,14 @@
jLabel3 = new javax.swing.JLabel();
jTextFieldTexture = new javax.swing.JTextField();
jCheckBoxDetail = new javax.swing.JCheckBox();
+ jLabel4 = new javax.swing.JLabel();
+ jSpinner1 = new javax.swing.JSpinner();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("ImgToMap");
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Convert image to map"));
- jTextFieldInput.setText("/home/maik/netbeans/ImgToMap/test1.png");
- jTextFieldInput.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- jTextFieldInputActionPerformed(evt);
- }
- });
-
jButtonInput.setText("Select input file");
jButtonInput.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -62,8 +65,6 @@
}
});
- jTextFieldOutput.setText("/tmp/test.map");
-
jButtonOutput.setText("Select output file");
jSpinnerUnits.setModel(new javax.swing.SpinnerNumberModel(256, 1, 2048, 1));
@@ -88,6 +89,10 @@
jCheckBoxDetail.setSelected(true);
jCheckBoxDetail.setText("make detail");
+ jLabel4.setText("Texture scale:");
+
+ jSpinner1.setModel(new javax.swing.SpinnerNumberModel(0.5d, 0.25d, 16.0d, 0.25d));
+
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
@@ -95,15 +100,15 @@
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jTextFieldTexture, javax.swing.GroupLayout.DEFAULT_SIZE, 421, Short.MAX_VALUE)
+ .addComponent(jTextFieldTexture, javax.swing.GroupLayout.DEFAULT_SIZE, 465, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jTextFieldInput, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
- .addComponent(jTextFieldOutput, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE))
+ .addComponent(jTextFieldInput, javax.swing.GroupLayout.DEFAULT_SIZE, 313, Short.MAX_VALUE)
+ .addComponent(jTextFieldOutput, javax.swing.GroupLayout.DEFAULT_SIZE, 313, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jButtonOutput, javax.swing.GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)
- .addComponent(jButtonInput, javax.swing.GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)))
+ .addComponent(jButtonOutput, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
+ .addComponent(jButtonInput, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)))
.addComponent(jButtonOK)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -114,9 +119,14 @@
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jSpinnerHeight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
- .addComponent(jCheckBoxDetail))
- .addComponent(jLabel2)))
- .addComponent(jLabel3))
+ .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel2)
+ .addGap(18, 18, 18)
+ .addComponent(jLabel4)))
+ .addGap(132, 132, 132))
+ .addComponent(jLabel3)
+ .addComponent(jCheckBoxDetail))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
@@ -133,17 +143,20 @@
.addGap(18, 18, 18)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
- .addComponent(jLabel2))
+ .addComponent(jLabel2)
+ .addComponent(jLabel4))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jSpinnerUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinnerHeight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jCheckBoxDetail))
+ .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTextFieldTexture, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(jCheckBoxDetail)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
.addComponent(jButtonOK)
.addContainerGap())
);
@@ -180,17 +193,14 @@
}
}//GEN-LAST:event_jButtonInputActionPerformed
-private void jTextFieldInputActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldInputActionPerformed
-// TODO add your handling code here:
-}//GEN-LAST:event_jTextFieldInputActionPerformed
-
private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed
Parameters p = new Parameters();
p.infile = jTextFieldInput.getText();
p.outfile = jTextFieldOutput.getText();
p.texture = jTextFieldTexture.getText();
- p.pixelsize = new Integer(jSpinnerUnits.getValue().toString());
- p.height = new Integer(jSpinnerHeight.getValue().toString());
+ p.pixelsize = (Integer)jSpinnerUnits.getValue();
+ p.height = (Integer)jSpinnerHeight.getValue();
+ p.texturescale = (Double)jSpinner1.getValue();
p.detail = jCheckBoxDetail.isSelected();
new MapWriter().writeMap(p);
}//GEN-LAST:event_jButtonOKActionPerformed
@@ -214,7 +224,9 @@
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
+ private javax.swing.JLabel jLabel4;
private javax.swing.JPanel jPanel1;
+ private javax.swing.JSpinner jSpinner1;
private javax.swing.JSpinner jSpinnerHeight;
private javax.swing.JSpinner jSpinnerUnits;
private javax.swing.JTextField jTextFieldInput;
Modified: trunk/tools/ImgToMap/src/imgtomap/Main.java
===================================================================
--- trunk/tools/ImgToMap/src/imgtomap/Main.java 2008-05-18 09:43:40 UTC (rev 3631)
+++ trunk/tools/ImgToMap/src/imgtomap/Main.java 2008-05-18 10:08:14 UTC (rev 3632)
@@ -1,7 +1,10 @@
-
package imgtomap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
/**
*
@@ -14,12 +17,19 @@
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
+
public void run() {
+
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception ex) {
+ // not critical, just ignore
+ }
+
JFrameMain frame = new JFrameMain();
frame.setVisible(true);
}
});
-
+
}
-
}
Modified: trunk/tools/ImgToMap/src/imgtomap/MapWriter.java
===================================================================
--- trunk/tools/ImgToMap/src/imgtomap/MapWriter.java 2008-05-18 09:43:40 UTC (rev 3631)
+++ trunk/tools/ImgToMap/src/imgtomap/MapWriter.java 2008-05-18 10:08:14 UTC (rev 3632)
@@ -24,7 +24,7 @@
if (!(new File(p.infile).exists())) {
return;
}
-
+
FileOutputStream fos;
try {
fos = new FileOutputStream(new File(p.outfile));
@@ -32,7 +32,7 @@
Logger.getLogger(MapWriter.class.getName()).log(Level.SEVERE, null, ex);
return;
}
-
+
double[][] height = getHeightmap(p.infile);
double units = 1d * p.pixelsize;
double max = p.height;
@@ -43,52 +43,56 @@
buf.append("{\n\"classname\" \"worldspawn\"\n");
// wander through grid
- for (int x = 0; x < height.length-1; ++x) {
- for (int y = 0; y < height[0].length-1; ++y) {
-
-
- /*
- *
- * a +-------+ b
- * / /|
- * / / |
- * / / |
- * c +-------+ d + f (e occluded, unused)
- * | | /
- * | | /
- * | |/
- * g +-------+ h
- *
- */
-
- Vector3D a = new Vector3D(x * units, -y * units, height[x][y] * max);
- Vector3D b = new Vector3D((x+1) * units, -y * units, height[x+1][y] * max);
- Vector3D c = new Vector3D(x * units, -(y+1) * units, height[x][y+1] * max);
- Vector3D d = new Vector3D((x+1) * units, -(y+1) * units, height[x+1][y+1] * max);
- //Vector3D e = new Vector3D(x * units, -y * units, -16.0);
- Vector3D f = new Vector3D((x+1) * units, -y * units, -16.0);
- Vector3D g = new Vector3D(x * units, -(y+1) * units, -16.0);
- Vector3D h = new Vector3D((x+1) * units, -(y+1) * units, -16.0);
-
- buf.append("{\n");
- buf.append(getMapPlaneString(a,b,d, p.detail, p.texture, p.texturescale));
- buf.append(getMapPlaneString(d,b,f, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(f,b,a, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(a,d,h, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(g,h,f, p.detail, "common/caulk", p.texturescale));
- buf.append("}\n");
-
-
- buf.append("{\n");
- buf.append(getMapPlaneString(d,c,a, p.detail, p.texture, p.texturescale));
- buf.append(getMapPlaneString(g,c,d, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(c,g,a, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(h,d,a, p.detail, "common/caulk", p.texturescale));
- buf.append(getMapPlaneString(g,h,f, p.detail, "common/caulk", p.texturescale));
- buf.append("}\n");
+ for (int x = 0; x < height.length - 1; ++x) {
+ for (int y = 0; y < height[0].length - 1; ++y) {
+
+ boolean skip = height[x][y] < 0 || height[x][y + 1] < 0 || height[x + 1][y] < 0 || height[x + 1][y + 1] < 0;
+
+ if (!skip) {
+
+ /*
+ *
+ * a +-------+ b
+ * / /|
+ * / / |
+ * / / |
+ * c +-------+ d + f (e occluded, unused)
+ * | | /
+ * | | /
+ * | |/
+ * g +-------+ h
+ *
+ */
+
+ Vector3D a = new Vector3D(x * units, -y * units, height[x][y] * max);
+ Vector3D b = new Vector3D((x + 1) * units, -y * units, height[x + 1][y] * max);
+ Vector3D c = new Vector3D(x * units, -(y + 1) * units, height[x][y + 1] * max);
+ Vector3D d = new Vector3D((x + 1) * units, -(y + 1) * units, height[x + 1][y + 1] * max);
+ //Vector3D e = new Vector3D(x * units, -y * units, -16.0);
+ Vector3D f = new Vector3D((x + 1) * units, -y * units, -16.0);
+ Vector3D g = new Vector3D(x * units, -(y + 1) * units, -16.0);
+ Vector3D h = new Vector3D((x + 1) * units, -(y + 1) * units, -16.0);
+
+ buf.append("{\n");
+ buf.append(getMapPlaneString(a, b, d, p.detail, p.texture, p.texturescale));
+ buf.append(getMapPlaneString(d, b, f, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(f, b, a, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(a, d, h, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(g, h, f, p.detail, "common/caulk", p.texturescale));
+ buf.append("}\n");
+
+
+ buf.append("{\n");
+ buf.append(getMapPlaneString(d, c, a, p.detail, p.texture, p.texturescale));
+ buf.append(getMapPlaneString(g, c, d, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(c, g, a, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(h, d, a, p.detail, "common/caulk", p.texturescale));
+ buf.append(getMapPlaneString(g, h, f, p.detail, "common/caulk", p.texturescale));
+ buf.append("}\n");
+ }
}
}
-
+
// worldspawn end
buf.append("}\n");
try {
@@ -172,17 +176,44 @@
int x = raster.getWidth();
int y = raster.getHeight();
-
double[][] result = new double[x][y];
for (int xi = 0; xi < x; ++xi) {
for (int yi = 0; yi < y; ++yi) {
float[] pixel = raster.getPixel(xi, yi, (float[]) null);
+
+ int channels;
+ boolean alpha;
+ if (pixel.length == 3) {
+ // RGB
+ channels = 3;
+ alpha = false;
+ } else if (pixel.length == 4) {
+ // RGBA
+ channels = 3;
+ alpha = true;
+ } else if (pixel.length == 1) {
+ // grayscale
+ channels = 1;
+ alpha = false;
+ } else {
+ // grayscale with alpha
+ channels = 1;
+ alpha = true;
+ }
+
float tmp = 0f;
- for (int i = 0; i < pixel.length; ++i) {
+ for (int i = 0; i < channels; ++i) {
tmp += pixel[i];
}
- result[xi][yi] = tmp / (pixel.length * 255f);
+ result[xi][yi] = tmp / (channels * 255f);
+
+ if (alpha) {
+ // mark this pixel to be skipped
+ if (pixel[pixel.length - 1] < 64.0) {
+ result[xi][yi] = -1.0;
+ }
+ }
}
}
More information about the nexuiz-commits
mailing list