~ubuntu-branches/ubuntu/precise/gnome-games/precise-proposed

« back to all changes in this revision

Viewing changes to glchess/src/3ds.vala

  • Committer: Package Import Robot
  • Author(s): Rodrigo Moya
  • Date: 2011-05-30 13:32:04 UTC
  • mfrom: (1.3.4)
  • mto: (163.1.3 precise)
  • mto: This revision was merged to the branch mainline in revision 143.
  • Revision ID: package-import@ubuntu.com-20110530133204-celaq1v1dsxc48q1
Tags: upstream-3.0.2
ImportĀ upstreamĀ versionĀ 3.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using GL;
 
2
 
 
3
public class TDSModel
 
4
{
 
5
    private GLfloat min_height = float.MAX;
 
6
    private GLfloat max_height = float.MIN;
 
7
    private GLfloat[] vertices;
 
8
    private GLushort[] triangles;
 
9
    private GLfloat[] normals;
 
10
    private GLfloat[] texture_coords;
 
11
 
 
12
    public TDSModel (File file) throws Error
 
13
    {
 
14
        var stream = file.read ();
 
15
        parse_block (stream, stream.query_info (FILE_ATTRIBUTE_STANDARD_SIZE).get_size ());
 
16
 
 
17
        /* Calculate normals */
 
18
        normals = new GLfloat[vertices.length];
 
19
        for (int i = 0; i < normals.length; i++)
 
20
            normals[i] = 0f;
 
21
        for (int i = 0; i < triangles.length; i += 3)
 
22
        {
 
23
            var v0 = triangles[i] * 3;
 
24
            var v1 = triangles[i+1] * 3;
 
25
            var v2 = triangles[i+2] * 3;
 
26
 
 
27
            /* Do cross-product of face to get normal */
 
28
            GLfloat a[3], b[3], normal[3];
 
29
            a[0] = vertices[v1] - vertices[v0];
 
30
            a[1] = vertices[v1+1] - vertices[v0+1];
 
31
            a[2] = vertices[v1+2] - vertices[v0+2];
 
32
            b[0] = vertices[v2] - vertices[v0];
 
33
            b[1] = vertices[v2+1] - vertices[v0+1];
 
34
            b[2] = vertices[v2+2] - vertices[v0+2];
 
35
            normal[0] = a[1]*b[2] - a[2]*b[1];
 
36
            normal[1] = a[2]*b[0] - a[0]*b[2];
 
37
            normal[2] = a[0]*b[1] - a[1]*b[0];
 
38
 
 
39
            /* Add this normal to the three vertices of this face */
 
40
            normals[v0] += normal[0];
 
41
            normals[v0+1] += normal[1];
 
42
            normals[v0+2] += normal[2];
 
43
            normals[v1] += normal[0];
 
44
            normals[v1+1] += normal[1];
 
45
            normals[v1+2] += normal[2];
 
46
            normals[v2] += normal[0];
 
47
            normals[v2+1] += normal[1];
 
48
            normals[v2+2] += normal[2];
 
49
        }
 
50
 
 
51
        /* Normalize normals */
 
52
        for (int i = 0; i < normals.length; i += 3)
 
53
        {
 
54
            GLfloat length = (GLfloat) Math.sqrt (normals[i]*normals[i] + normals[i+1]*normals[i+1] + normals[i+2]*normals[i+2]);
 
55
            normals[i] /= length;
 
56
            normals[i+1] /= length;
 
57
            normals[i+2] /= length;
 
58
        }
 
59
 
 
60
        /* Set texture coordinates to a conical projection */
 
61
        texture_coords = new GLfloat[(vertices.length / 3) * 2];
 
62
        for (int i = 0, j = 0; i < vertices.length; i += 3, j += 2)
 
63
        {
 
64
            var u = vertices[i];
 
65
            var v = vertices[i+2];
 
66
            var r = (GLfloat) Math.sqrt (u*u + v*v);
 
67
            if (r != 0)
 
68
            {
 
69
                u /= r;
 
70
                v /= r;
 
71
            }
 
72
 
 
73
            /* Maximum height is in the middle of the texture, minimum on the boundary */
 
74
            var h = 1.0f - (vertices[i+1] / max_height);
 
75
            texture_coords[j] = 0.5f + 0.5f * h * u;
 
76
            texture_coords[j+1] = 0.5f + 0.5f * h * v;
 
77
        }
 
78
    }
 
79
    
 
80
    private void parse_block (FileInputStream stream, int64 length) throws Error
 
81
    {
 
82
        while (length > 6)
 
83
        {
 
84
            var id = read_uint16 (stream);
 
85
            int64 block_length = read_uint32 (stream);
 
86
            if (block_length < 6)
 
87
            {
 
88
                return;
 
89
            }
 
90
            if (block_length > length)
 
91
            {
 
92
                // throw error
 
93
                stderr.printf("Overflow, need %lli octets for %04X, but only have %lli\n", block_length, (int) id, length);
 
94
                return;
 
95
            }
 
96
 
 
97
            switch (id)
 
98
            {
 
99
            /* Main chunk */
 
100
            case 0x4D4D:
 
101
                //stdout.printf("<root>\n");
 
102
                parse_block (stream, block_length - 6);
 
103
                //stdout.printf("</root>\n");
 
104
                break;
 
105
 
 
106
            /* Version */
 
107
            /*case 0x0002:
 
108
                var version = read_uint32 (stream);
 
109
                //stdout.printf("<version>%u</version>\n", version);
 
110
                break;*/
 
111
 
 
112
            /* 3D editor */
 
113
            case 0x3D3D:
 
114
                //stdout.printf("<editor>\n");
 
115
                parse_block (stream, block_length - 6);
 
116
                //stdout.printf("</editor>\n");
 
117
                break;
 
118
 
 
119
            /* Object block */
 
120
            case 0x4000:
 
121
                var name = read_string (stream);
 
122
                //stdout.printf("<object name=\"%s\">\n", name);
 
123
                parse_block (stream, block_length - 6 - (name.length + 1));
 
124
                //stdout.printf("</object>\n");
 
125
                break;
 
126
                
 
127
            /* Triangular mesh */
 
128
            case 0x4100:
 
129
                //stdout.printf("<triangles>\n");
 
130
                parse_block (stream, block_length - 6);
 
131
                //stdout.printf("</triangles>\n");
 
132
                break;
 
133
 
 
134
            /* Vertices */
 
135
            case 0x4110:
 
136
                //stdout.printf("<vertices>\n");
 
137
                var n = read_uint16 (stream);
 
138
                vertices = new GLfloat[n*3];
 
139
                for (var i = 0; i < n; i++)
 
140
                {
 
141
                    var x = read_float (stream);
 
142
                    var y = read_float (stream);
 
143
                    var z = read_float (stream);
 
144
                    var scale = 3.5f; // FIXME: Fix the model files
 
145
                    vertices[i*3] = scale*x;
 
146
                    vertices[i*3+1] = scale*z;
 
147
                    vertices[i*3+2] = scale*y;
 
148
 
 
149
                    var h = scale*z;
 
150
                    if (h < min_height)
 
151
                        min_height = h;
 
152
                    if (h > max_height)
 
153
                        max_height = h;
 
154
 
 
155
                    //stdout.printf ("<vertex x=\"%f\" y=\"%f\" z=\"%f\"/>\n", x, y, z);
 
156
                }
 
157
                //stdout.printf("</vertices>\n");
 
158
                break;
 
159
 
 
160
            /* Faces */
 
161
            case 0x4120:
 
162
                //stdout.printf("<faces>\n");
 
163
                if (block_length < 2)
 
164
                    return;
 
165
                var n = read_uint16 (stream);
 
166
                triangles = new GLushort[n*3];
 
167
                if (block_length < 2 + n * 8)                  
 
168
                {
 
169
                    stderr.printf("Invalid face data, need %u, have %lli\n", 2+n*8, block_length);
 
170
                    return;
 
171
                }
 
172
                for (var i = 0; i < n; i++)
 
173
                {
 
174
                    var a = read_uint16 (stream);
 
175
                    var b = read_uint16 (stream);
 
176
                    var c = read_uint16 (stream);
 
177
                    /*var flags = */read_uint16 (stream);
 
178
                    triangles[i*3] = (GLushort) a;
 
179
                    triangles[i*3+1] = (GLushort) c;
 
180
                    triangles[i*3+2] = (GLushort) b;
 
181
                    //stdout.printf ("<face a=\"%u\" b=\"%u\" c=\"%u\"/ flags=\"%u\">\n", a, b, c, flags);
 
182
                }
 
183
                parse_block (stream, block_length - (2 + n*8));
 
184
                //stdout.printf("</faces>\n");
 
185
                break;
 
186
 
 
187
            /* Keyframer */
 
188
/*            case 0xB000:
 
189
                //stdout.printf("<keyframe>\n");
 
190
                parse_block (stream, block_length - 6);
 
191
                //stdout.printf("</keyframe>\n");
 
192
                break;*/
 
193
 
 
194
            default:
 
195
                //stdout.printf ("<%04X>", id);
 
196
                for (var i = 0; i < block_length - 6; i++)
 
197
                {
 
198
                    /*var c = */read_uint8 (stream);
 
199
                    //stdout.printf("%02X ", c);
 
200
                }
 
201
                //stdout.printf ("<\\%04X>\n", id);
 
202
                break;
 
203
            }
 
204
 
 
205
            length -= block_length;
 
206
                //stream.seek (block_length - 6, SeekType.CUR);
 
207
        }
 
208
        
 
209
        if (length != 0)
 
210
        {
 
211
            return; // throw error
 
212
        }
 
213
    }
 
214
 
 
215
    public void render ()
 
216
    {
 
217
        glEnable (GL_CULL_FACE);
 
218
 
 
219
        glEnableClientState (GL_VERTEX_ARRAY);
 
220
        glEnableClientState (GL_NORMAL_ARRAY);
 
221
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
222
 
 
223
        glVertexPointer (3, GL_FLOAT, 0, vertices);
 
224
        glNormalPointer (GL_FLOAT, 0, normals);
 
225
        glTexCoordPointer (2, GL_FLOAT, 0, texture_coords);
 
226
        glDrawElements (GL_TRIANGLES, (GLsizei) triangles.length, GL_UNSIGNED_SHORT, triangles);
 
227
 
 
228
        glDisableClientState (GL_VERTEX_ARRAY);
 
229
        glDisableClientState (GL_NORMAL_ARRAY);
 
230
        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
 
231
    }
 
232
 
 
233
    private uint8 read_uint8 (InputStream stream) throws Error
 
234
    {
 
235
        uchar buffer[1];
 
236
        stream.read_all (buffer, null, null);
 
237
        return buffer[0];
 
238
    }
 
239
 
 
240
    private uint16 read_uint16 (InputStream stream) throws Error
 
241
    {
 
242
        uchar buffer[2];
 
243
        stream.read_all (buffer, null, null);
 
244
        return buffer[1] << 8 | buffer[0];
 
245
    }
 
246
 
 
247
    private uint32 read_uint32 (InputStream stream) throws Error
 
248
    {
 
249
        uchar buffer[4];
 
250
        stream.read_all (buffer, null, null);
 
251
        return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
 
252
    }
 
253
 
 
254
    private float read_float (InputStream stream) throws Error
 
255
    {
 
256
        uint8 buffer[4];
 
257
        stream.read_all (buffer, null, null);
 
258
        float[] fbuffer = (float[]) buffer;
 
259
        return fbuffer[0];
 
260
    }
 
261
 
 
262
    private string read_string (InputStream stream) throws Error
 
263
    {
 
264
        var value = new StringBuilder();
 
265
        while (true)
 
266
        {
 
267
            var c = read_uint8 (stream);
 
268
            if (c == 0)
 
269
                return value.str;
 
270
            value.append_c ((char)c);
 
271
        }
 
272
    }
 
273
}
 
 
b'\\ No newline at end of file'