]> icculus.org git repositories - divverent/nexuiz.git/blob - tools/ImgToMap/src/imgtomap/MapWriter.java
add new tool to create maps from heightmaps
[divverent/nexuiz.git] / tools / ImgToMap / src / imgtomap / MapWriter.java
1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5 package imgtomap;
6
7 import java.awt.image.BufferedImage;
8 import java.awt.image.Raster;
9 import java.io.File;
10 import java.io.FileNotFoundException;
11 import java.io.FileOutputStream;
12 import java.io.IOException;
13 import java.util.logging.Level;
14 import java.util.logging.Logger;
15 import javax.imageio.ImageIO;
16
17 /**
18  *
19  * @author maik
20  */
21 public class MapWriter {
22
23     public void writeMap(Parameters p) {
24         if (!(new File(p.infile).exists())) {
25             return;
26         }
27         
28         FileOutputStream fos;
29         try {
30             fos = new FileOutputStream(new File(p.outfile));
31         } catch (FileNotFoundException ex) {
32             Logger.getLogger(MapWriter.class.getName()).log(Level.SEVERE, null, ex);
33             return;
34         }
35            
36         double[][] height = getHeightmap(p.infile);
37         double units = 1d * p.pixelsize;
38         double max = p.height;
39
40         StringBuffer buf = new StringBuffer();
41
42         // worldspawn start
43         buf.append("{\n\"classname\" \"worldspawn\"\n");
44
45         // wander through grid
46         for (int x = 0; x < height.length-1; ++x) {
47             for (int y = 0; y < height[0].length-1; ++y) {
48                 
49                 
50                 /*
51                  * 
52                  *      a +-------+ b
53                  *       /       /|
54                  *      /       / |
55                  *     /       /  |
56                  *  c +-------+ d + f   (e occluded, unused)
57                  *    |       |  /
58                  *    |       | /
59                  *    |       |/
60                  *  g +-------+ h
61                  * 
62                  */
63                 
64                 Vector3D a = new Vector3D(x * units, -y * units, height[x][y] * max);
65                 Vector3D b = new Vector3D((x+1) * units, -y * units, height[x+1][y] * max);
66                 Vector3D c = new Vector3D(x * units, -(y+1) * units, height[x][y+1] * max);
67                 Vector3D d = new Vector3D((x+1) * units, -(y+1) * units, height[x+1][y+1] * max);
68                 //Vector3D e = new Vector3D(x * units, -y * units, -16.0);
69                 Vector3D f = new Vector3D((x+1) * units, -y * units, -16.0);
70                 Vector3D g = new Vector3D(x * units, -(y+1) * units, -16.0);
71                 Vector3D h = new Vector3D((x+1) * units, -(y+1) * units, -16.0);
72                 
73                 buf.append("{\n");
74                 buf.append(getMapPlaneString(a,b,d, p.detail, p.texture, p.texturescale));
75                 buf.append(getMapPlaneString(d,b,f, p.detail, "common/caulk", p.texturescale));
76                 buf.append(getMapPlaneString(f,b,a, p.detail, "common/caulk", p.texturescale));
77                 buf.append(getMapPlaneString(a,d,h, p.detail, "common/caulk", p.texturescale));
78                 buf.append(getMapPlaneString(g,h,f, p.detail, "common/caulk", p.texturescale));
79                 buf.append("}\n");
80                 
81                 
82                 buf.append("{\n");
83                 buf.append(getMapPlaneString(d,c,a, p.detail, p.texture, p.texturescale));
84                 buf.append(getMapPlaneString(g,c,d, p.detail, "common/caulk", p.texturescale));
85                 buf.append(getMapPlaneString(c,g,a, p.detail, "common/caulk", p.texturescale));
86                 buf.append(getMapPlaneString(h,d,a, p.detail, "common/caulk", p.texturescale));
87                 buf.append(getMapPlaneString(g,h,f, p.detail, "common/caulk", p.texturescale));
88                 buf.append("}\n");
89             }
90         }
91         
92         // worldspawn end
93         buf.append("}\n");
94         try {
95             fos.write(buf.toString().getBytes());
96         } catch (IOException ex) {
97             Logger.getLogger(MapWriter.class.getName()).log(Level.SEVERE, null, ex);
98         }
99     }
100
101     private String getMapPlaneString(Vector3D p1, Vector3D p2, Vector3D p3, boolean detail, String material, double scale) {
102         int flag;
103         if (detail) {
104             flag = 134217728;
105         } else {
106             flag = 0;
107         }
108         return "( " + p1.x + " " + p1.y + " " + p1.z + " ) ( " + p2.x + " " + p2.y + " " + p2.z + " ) ( " + p3.x + " " + p3.y + " " + p3.z + " ) " + material + " 0 0 0 " + scale + " " + scale + " " + flag + " 0 0\n";
109     }
110
111     private class Vector3D {
112
113         public double x,  y,  z;
114
115         public Vector3D() {
116             this(0.0, 0.0, 0.0);
117         }
118
119         public Vector3D(double x, double y, double z) {
120             this.x = x;
121             this.y = y;
122             this.z = z;
123         }
124
125         public Vector3D crossproduct(Vector3D p1) {
126             Vector3D result = new Vector3D();
127
128             result.x = this.y * p1.z - this.z * p1.y;
129             result.y = this.z * p1.x - this.x * p1.z;
130             result.z = this.x * p1.y - this.y * p1.x;
131
132             return result;
133         }
134
135         public double dotproduct(Vector3D p1) {
136             return this.x * p1.x + this.y * p1.y + this.z * p1.z;
137         }
138
139         public Vector3D substract(Vector3D p1) {
140             Vector3D result = new Vector3D();
141
142             result.x = this.x - p1.x;
143             result.y = this.y - p1.y;
144             result.z = this.z - p1.z;
145
146             return result;
147         }
148
149         public void scale(double factor) {
150             x *= factor;
151             y *= factor;
152             z *= factor;
153         }
154
155         public double length() {
156             return Math.sqrt((x * x) + (y * y) + (z * z));
157         }
158
159         public void normalize() {
160             double l = length();
161
162             x /= l;
163             y /= l;
164             z /= l;
165         }
166     }
167
168     private double[][] getHeightmap(String file) {
169         try {
170             BufferedImage bimg = ImageIO.read(new File(file));
171             Raster raster = bimg.getRaster();
172             int x = raster.getWidth();
173             int y = raster.getHeight();
174
175
176             double[][] result = new double[x][y];
177
178             for (int xi = 0; xi < x; ++xi) {
179                 for (int yi = 0; yi < y; ++yi) {
180                     float[] pixel = raster.getPixel(xi, yi, (float[]) null);
181                     float tmp = 0f;
182                     for (int i = 0; i < pixel.length; ++i) {
183                         tmp += pixel[i];
184                     }
185                     result[xi][yi] = tmp / (pixel.length * 255f);
186                 }
187             }
188
189
190             return result;
191         } catch (IOException ex) {
192             Logger.getLogger(MapWriter.class.getName()).log(Level.SEVERE, null, ex);
193         }
194
195         return null;
196     }
197 }