Subversion Repositories eduke32

Rev

Rev 6074 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1784 helixhorne 1
 
2
#include "compat.h"
3
#include "build.h"
6656 pogokeen 4
#include "glad/glad.h"
1784 helixhorne 5
#include "mdsprite.h"
6
 
7
 
8
static md2head_t head;
9
 
10
 
11
static void quit(int32_t status)
12
{
13
    exit(status);
14
}
15
 
16
static md2model_t *md2load(int *fd, const char *filename, int32_t ronly)
17
{
18
    md2model_t *m;
19
    int fil;
20
 
21
    fil = Bopen(filename, ronly?BO_RDONLY:BO_RDWR);
22
    if (fil<0)
23
    {
2521 hendricks2 24
        Bfprintf(stderr, "Couldn't open `%s': %s\n", filename, strerror(errno));
1784 helixhorne 25
        quit(2);
26
    }
27
 
28
    m = (md2model_t *)Bcalloc(1,sizeof(md2model_t)); if (!m) quit(1);
29
    m->mdnum = 2; m->scale = .01f;
30
 
31
    Bread(fil,(char *)&head,sizeof(md2head_t));
32
 
33
    head.id = B_LITTLE32(head.id);                 head.vers = B_LITTLE32(head.vers);
34
    head.skinxsiz = B_LITTLE32(head.skinxsiz);     head.skinysiz = B_LITTLE32(head.skinysiz);
35
    head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins);
36
    head.numverts = B_LITTLE32(head.numverts);     head.numuv = B_LITTLE32(head.numuv);
37
    head.numtris = B_LITTLE32(head.numtris);       head.numglcmds = B_LITTLE32(head.numglcmds);
38
    head.numframes = B_LITTLE32(head.numframes);   head.ofsskins = B_LITTLE32(head.ofsskins);
39
    head.ofsuv = B_LITTLE32(head.ofsuv);           head.ofstris = B_LITTLE32(head.ofstris);
40
    head.ofsframes = B_LITTLE32(head.ofsframes);   head.ofsglcmds = B_LITTLE32(head.ofsglcmds);
41
    head.ofseof = B_LITTLE32(head.ofseof);
42
 
43
    if ((head.id != 0x32504449) || (head.vers != 8))
44
    {
2521 hendricks2 45
        Bfprintf(stderr, "File `%s' is not an md2 file.\n", filename);
1784 helixhorne 46
        quit(3);
47
    } //"IDP2"
48
 
49
    m->numskins = head.numskins;
50
    m->numframes = head.numframes;
51
    m->numverts = head.numverts;
52
    m->numglcmds = head.numglcmds;
53
    m->framebytes = head.framebytes;
54
 
55
    m->frames = (char *)Bmalloc(m->numframes*m->framebytes); if (!m->frames) quit(1);
56
    m->tris = (md2tri_t *)Bmalloc(head.numtris*sizeof(md2tri_t)); if (!m->tris) quit(1);
57
    m->uv = (md2uv_t *)Bmalloc(head.numuv*sizeof(md2uv_t)); if (!m->uv) quit(1);
58
 
59
    Blseek(fil,head.ofsframes,SEEK_SET);
60
    if (Bread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
61
        quit(1);
62
 
63
    Blseek(fil,head.ofstris,SEEK_SET);
64
    if (Bread(fil,(char *)m->tris,head.numtris*sizeof(md2tri_t)) != (int32_t)(head.numtris*sizeof(md2tri_t)))
65
        quit(1);
66
 
67
    Blseek(fil,head.ofsuv,SEEK_SET);
68
    if (Bread(fil,(char *)m->uv,head.numuv*sizeof(md2uv_t)) != (int32_t)(head.numuv*sizeof(md2uv_t)))
69
        quit(1);
70
 
71
#if B_BIG_ENDIAN != 0
72
    {
73
        char *f = (char *)m->frames;
74
        int32_t *l,i,j;
75
        md2frame_t *fr;
76
 
77
        for (i = m->numframes-1; i>=0; i--)
78
        {
79
            fr = (md2frame_t *)f;
80
            l = (int32_t *)&fr->mul;
81
            for (j=5; j>=0; j--) l[j] = B_LITTLE32(l[j]);
82
            f += m->framebytes;
83
        }
84
 
85
        for (i = head.numtris-1; i>=0; i--)
86
        {
87
            m->tris[i].v[0] = B_LITTLE16(m->tris[i].v[0]);
88
            m->tris[i].v[1] = B_LITTLE16(m->tris[i].v[1]);
89
            m->tris[i].v[2] = B_LITTLE16(m->tris[i].v[2]);
90
            m->tris[i].u[0] = B_LITTLE16(m->tris[i].u[0]);
91
            m->tris[i].u[1] = B_LITTLE16(m->tris[i].u[1]);
92
            m->tris[i].u[2] = B_LITTLE16(m->tris[i].u[2]);
93
        }
94
        for (i = head.numuv-1; i>=0; i--)
95
        {
96
            m->uv[i].u = B_LITTLE16(m->uv[i].u);
97
            m->uv[i].v = B_LITTLE16(m->uv[i].v);
98
        }
99
    }
100
#endif
101
 
102
    *fd = fil;
103
    return(m);
104
}
105
 
106
 
107
static void usage_and_quit()
108
{
2521 hendricks2 109
    Bfprintf(stderr,
1784 helixhorne 110
            "Usage:\n"
111
            "   md2tool <modelfile>.md2:  display info about model\n"
112
            "   md2tool -minmax <minx>,<miny>,<minz>:<maxx>,<maxy>,<maxz> <modelfile>.md2:\n"
113
            "      modify `scale' and `translate' fields of MD2 (in-place) to produce given bounds\n"
114
        );
115
    quit(1);
116
}
117
 
118
int main(int argc, char **argv)
119
{
120
    char *fn=NULL, *cp;
2472 hendricks2 121
    int32_t fd=-1, i, j;
1784 helixhorne 122
 
123
    int32_t doinfo=1;
124
 
125
    // md2 mul[x,y,z], add[x,y,z]
126
    float mx,my,mz, ax,ay,az;
127
 
128
    // desired model bounds
129
    float dminx=0,dminy=0,dminz=0, dmaxx=1,dmaxy=1,dmaxz=1;
130
 
131
    // md2 uint8-coordinate bounds
132
    uint8_t maxv[3]={0,0,0};
133
    uint8_t minv[3]={255,255,255};
134
 
2473 hendricks2 135
    md2frame_t *fr;
1784 helixhorne 136
    uint8_t *vp;
137
 
138
    md2model_t *m;
139
 
140
    if (argc<=1)
141
        usage_and_quit();
142
 
143
    for (i=1; i<argc; i++)
144
    {
145
        cp = argv[i];
146
 
147
        if (cp[0]=='-')
148
        {
149
            if (!strcmp(cp, "-minmax"))
150
            {
151
                doinfo=0;
152
                if (i+1 >= argc)
153
                    usage_and_quit();
2521 hendricks2 154
                if (Bsscanf(argv[i+1], "%f,%f,%f:%f,%f,%f", &dminx,&dminy,&dminz, &dmaxx,&dmaxy,&dmaxz)!=6)
1784 helixhorne 155
                    usage_and_quit();
156
                i++;
157
            }
158
            else
159
            {
2521 hendricks2 160
                Bfprintf(stderr, "unrecognized option `%s'\n", cp);
1784 helixhorne 161
                quit(2);
162
            }
163
        }
164
        else
165
            fn = cp;
166
    }
167
 
168
    if (!fn)
169
        usage_and_quit();
170
 
171
    m = md2load(&fd, fn, doinfo);
172
 
173
    fr = (md2frame_t *)m->frames;
174
    mx=fr->mul.x; my=fr->mul.y; mz=fr->mul.z;
175
    ax=fr->add.x; ay=fr->add.y; az=fr->add.z;
176
 
177
    for (i=0, vp=fr->verts->v; i<m->numverts; i++, vp+=sizeof(md2vert_t))
178
    {
179
        for (j=0; j<3; j++)
180
        {
181
            maxv[j] = max(maxv[j], vp[j]);
182
            minv[j] = min(minv[j], vp[j]);
183
        }
184
    }
185
 
186
    if (doinfo)
187
    {
2521 hendricks2 188
        Bprintf("------ %s ------\n", fn);
189
        Bprintf("numframes: %d\n", m->numframes);
190
        Bprintf("numverts: %d\n", m->numverts);
191
        Bprintf("numtris: %d\n", head.numtris);
192
        Bprintf("\n");
193
        Bprintf("ofsframes: %x\n", head.ofsframes);
194
        Bprintf("framebytes: %d\n", head.framebytes);
195
//        Bprintf("framebytes: %d, calculated=%d\n", head.framebytes, sizeof(md2frame_t)+(m->numverts-1)*sizeof(md2vert_t));
196
        Bprintf("\n");
1784 helixhorne 197
 
2521 hendricks2 198
        Bprintf("mul=%f %f %f\n", mx, my, mz);
199
        Bprintf("add=%f %f %f\n", ax, ay, az);
1784 helixhorne 200
 
2521 hendricks2 201
        Bprintf("min xyz (s+t) = %f %f %f\n", minv[0]*mx+ax, minv[1]*my+ay, minv[2]*mz+az);
202
        Bprintf("max xyz (s+t) = %f %f %f\n", maxv[0]*mx+ax, maxv[1]*my+ay, maxv[2]*mz+az);
1784 helixhorne 203
 
2521 hendricks2 204
        Bprintf("\n");
1784 helixhorne 205
    }
206
    else
207
    {
208
        if (maxv[0]-minv[0]>0) mx = (dmaxx-dminx)/(maxv[0]-minv[0]); else mx=0;
209
        if (maxv[1]-minv[1]>0) my = (dmaxy-dminy)/(maxv[1]-minv[1]); else my=0;
210
        if (maxv[2]-minv[2]>0) mz = (dmaxz-dminz)/(maxv[2]-minv[2]); else mz=0;
211
 
212
        if (mx==0||my==0||mz==0)
213
        {
2521 hendricks2 214
            Bfprintf(stderr, "max[x,y,z]-min[x,y,z] must each be grater 0!\n");
1784 helixhorne 215
            quit(2);
216
        }
217
 
218
        ax = dmaxx-maxv[0]*mx;
219
        ay = dmaxy-maxv[1]*my;
220
        az = dmaxz-maxv[2]*mz;
221
 
222
#define ISNAN(x) ((x)!=(x))
223
#define ISINF(x) ((x!=0)&&(x/2==x))
224
 
225
        if (ISNAN(mx)||ISNAN(my)||ISNAN(mz)||ISNAN(ax)||ISNAN(ay)||ISNAN(az)||
226
            ISINF(mx)||ISINF(my)||ISINF(mz)||ISINF(ax)||ISINF(ay)||ISINF(az))
227
        {
2521 hendricks2 228
            Bfprintf(stderr, "Calculation resulted in NaN or Inf.\n");
1784 helixhorne 229
            quit(2);
230
        }
231
 
232
        Blseek(fd,head.ofsframes,SEEK_SET);
233
        if (Bwrite(fd, &mx, sizeof(mx))!=sizeof(mx)) { perror("write"); quit(3); }
234
        if (Bwrite(fd, &my, sizeof(my))!=sizeof(my)) { perror("write"); quit(3); }
235
        if (Bwrite(fd, &mz, sizeof(mz))!=sizeof(mz)) { perror("write"); quit(3); }
236
        if (Bwrite(fd, &ax, sizeof(ax))!=sizeof(ax)) { perror("write"); quit(3); }
237
        if (Bwrite(fd, &ay, sizeof(ay))!=sizeof(ay)) { perror("write"); quit(3); }
238
        if (Bwrite(fd, &az, sizeof(az))!=sizeof(az)) { perror("write"); quit(3); }
239
        Bclose(fd);
240
 
2521 hendricks2 241
        Bprintf("wrote scale and translate of `%s'.\n", fn);
1784 helixhorne 242
    }
243
 
244
    return 0;
245
}