1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: fixmd2.cpp 1599 2006-07-06 17:20:16Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 // HEADER FILES ------------------------------------------------------------
27 
28 #include "cmdlib.h"
29 using namespace VavoomUtils;
30 #include "fmd2defs.h"
31 
32 // MACROS ------------------------------------------------------------------
33 
34 // TYPES -------------------------------------------------------------------
35 
36 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
37 
38 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
39 
40 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
41 
42 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
43 
44 // PUBLIC DATA DEFINITIONS -------------------------------------------------
45 
46 // PRIVATE DATA DEFINITIONS ------------------------------------------------
47 
48 static char			filename[256];
49 static mmdl_t		*model;
50 
51 // CODE --------------------------------------------------------------------
52 
53 //==========================================================================
54 //
55 //	LoadModel
56 //
57 //==========================================================================
58 
LoadModel()59 static void LoadModel()
60 {
61 	LoadFile(filename, (void**)&model);
62 	if (model->ident != IDPOLY2HEADER)
63 		Error("Not a model");
64 	if (model->version != ALIAS_VERSION)
65 		Error("Bad version");
66 }
67 
68 //==========================================================================
69 //
70 //	WriteModel
71 //
72 //==========================================================================
73 
WriteModel()74 static void WriteModel()
75 {
76 	FILE *f = fopen(filename, "wb");
77 	fwrite(model, 1, model->ofsend, f);
78 	fclose(f);
79 }
80 
81 //==========================================================================
82 //
83 //	ScaleModel
84 //
85 //==========================================================================
86 
ScaleModel(double scale)87 static void ScaleModel(double scale)
88 {
89 	mframe_t *frame = (mframe_t*)((vuint8*)model + model->ofsframes);
90 	for (int i = 0; i < model->numframes; i++)
91 	{
92 		frame->scale[0] *= scale;
93 		frame->scale[1] *= scale;
94 		frame->scale[2] *= scale;
95 		frame->scale_origin[0] *= scale;
96 		frame->scale_origin[1] *= scale;
97 		frame->scale_origin[2] *= scale;
98 		frame = (mframe_t*)((vuint8*)frame + model->framesize);
99 	}
100 }
101 
102 //==========================================================================
103 //
104 //	ScaleModelNoOrigin
105 //
106 //==========================================================================
107 
ScaleModelNoOrigin(double scale)108 static void ScaleModelNoOrigin(double scale)
109 {
110 	mframe_t *frame = (mframe_t*)((vuint8*)model + model->ofsframes);
111 	for (int i = 0; i < model->numframes; i++)
112 	{
113 		frame->scale[0] *= scale;
114 		frame->scale[1] *= scale;
115 		frame->scale[2] *= scale;
116 		frame = (mframe_t*)((vuint8*)frame + model->framesize);
117 	}
118 }
119 
120 //==========================================================================
121 //
122 //	ShiftModel
123 //
124 //==========================================================================
125 
ShiftModel(double x,double y,double z)126 static void ShiftModel(double x, double y, double z)
127 {
128 	mframe_t *frame = (mframe_t*)((vuint8*)model + model->ofsframes);
129 	for (int i = 0; i < model->numframes; i++)
130 	{
131 		frame->scale_origin[0] += x;
132 		frame->scale_origin[1] += y;
133 		frame->scale_origin[2] += z;
134 		frame = (mframe_t*)((vuint8*)frame + model->framesize);
135 	}
136 }
137 
138 //==========================================================================
139 //
140 //	FixModelSkin
141 //
142 //==========================================================================
143 
FixModelSkin(const char * name)144 static void FixModelSkin(const char *name)
145 {
146 	mskin_t *skin = (mskin_t*)((vuint8*)model + model->ofsskins);
147 	strncpy(skin->name, name, sizeof(skin->name));
148 }
149 
150 //==========================================================================
151 //
152 //	MoveSTVerts
153 //
154 //==========================================================================
155 
MoveSTVerts(const char * str)156 static void MoveSTVerts(const char *str)
157 {
158 	int			olds1, oldt1;
159 	int			olds2, oldt2;
160 	int			news, newt;
161 	char		*sp;
162 	mstvert_t	*vert;
163 	int			i;
164 
165 	olds1 = strtol(str, &sp, 0);
166 	if (*sp != ',')
167 		Error("Bad syntax");
168 	sp++;
169 	oldt1 = strtol(sp, &sp, 0);
170 	if (*sp != ',')
171 		Error("Bad syntax");
172 	sp++;
173 	olds2 = strtol(sp, &sp, 0);
174 	if (*sp != ',')
175 		Error("Bad syntax");
176 	sp++;
177 	oldt2 = strtol(sp, &sp, 0);
178 	if (*sp != ',')
179 		Error("Bad syntax");
180 	sp++;
181 	news = strtol(sp, &sp, 0);
182 	if (*sp != ',')
183 		Error("Bad syntax");
184 	sp++;
185 	newt = strtol(sp, &sp, 0);
186 	if (*sp)
187 		Error("Bad syntax");
188 
189 	vert = (mstvert_t*)((vuint8*)model + model->ofsstverts);
190 	for (i = 0; i < model->numstverts; i++)
191 	{
192 		if (vert[i].s >= olds1 && vert[i].t >= oldt1 &&
193 			vert[i].s < olds2 && vert[i].t < oldt2)
194 		{
195 			vert[i].s = vert[i].s - olds1 + news;
196 			vert[i].t = vert[i].t - oldt1 + newt;
197 		}
198 	}
199 	//FIXME process GL commands
200 }
201 
202 //==========================================================================
203 //
204 //	main
205 //
206 //==========================================================================
207 
main(int argc,char * argv[])208 int main(int argc, char *argv[])
209 {
210 	if (argc < 2)
211 	{
212 		fprintf(stderr, "Usage: fixmd2 <model> [options]\n");
213 		fprintf(stderr, "Options are:\n");
214 		fprintf(stderr, "  s<scale>  - scale model by scale\n");
215 		fprintf(stderr, "  i<iscale> - scale model by 1/iscale\n");
216 		fprintf(stderr, "  x<shift>  - shift origin on x\n");
217 		fprintf(stderr, "  y<shift>  - shift origin on y\n");
218 		fprintf(stderr, "  z<shift>  - shift origin on z\n");
219 		fprintf(stderr, "  /<name>   - set skin\n");
220 		return -1;
221 	}
222 	strcpy(filename, argv[1]);
223 	LoadModel();
224 	for (int i = 2; i < argc; i++)
225 	{
226 		if (argv[i][0] == 's')
227 		{
228 			ScaleModel(atof(argv[i] + 1));
229 		}
230 		else if (argv[i][0] == 'S')
231 		{
232 			ScaleModelNoOrigin(atof(argv[i] + 1));
233 		}
234 		else if (argv[i][0] == 'i')
235 		{
236 			ScaleModel(1.0 / atof(argv[i] + 1));
237 		}
238 		else if (argv[i][0] == 'x')
239 		{
240 			ShiftModel(atof(argv[i] + 1), 0, 0);
241 		}
242 		else if (argv[i][0] == 'y')
243 		{
244 			ShiftModel(0, atof(argv[i] + 1), 0);
245 		}
246 		else if (argv[i][0] == 'z')
247 		{
248 			ShiftModel(0, 0, atof(argv[i] + 1));
249 		}
250 		else if (argv[i][0] == '/')
251 		{
252 			FixModelSkin(argv[i] + 1);
253 		}
254 		else if (argv[i][0] == 'm')
255 		{
256 			MoveSTVerts(argv[i] + 1);
257 		}
258 		else
259 		{
260 			Error("Bad args\n");
261 		}
262 	}
263 	WriteModel();
264 	return 0;
265 }
266