Subversion Repositories spk

Rev

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

Rev Author Line No. Line
1 cycrow 1
#include "bob_dom_bob.h"
114 cycrow 2
 
3
#include "bob_stream_operators.h"
1 cycrow 4
//---------------------------------------------------------------------------------
5
// BOB file
114 cycrow 6
bool bob_dom_bob::load(ibinaryfilestream& is)
1 cycrow 7
{
114 cycrow 8
	int hdr;
1 cycrow 9
	is >> hdr;
114 cycrow 10
	if(hdr!=HDR_BEGIN){
1 cycrow 11
		error(e_badHeader);
12
		return false;
13
	}
114 cycrow 14
 
15
	if(peek(is)==bob_info::HDR_BEGIN){
1 cycrow 16
		if(!info.load(is)){
17
			for(ErrorIterator &it=info.errors.begin(); it!=info.errors.end(); ++it){
18
				error(it->code, "info: %s", it->text);
19
			}
20
			return false;
21
		}
22
	}
114 cycrow 23
 
1 cycrow 24
	if(materials.load(is)==false){
25
		for(ErrorIterator &it=materials.errors.begin(); it!=materials.errors.end(); ++it){
26
			error(it->code, "materials->%s", it->text);
27
			return false;
28
		}
29
	}
114 cycrow 30
 
1 cycrow 31
	if(bodies.load(is)==false){
32
		for(ErrorIterator &it=bodies.errors.begin(); it!=bodies.errors.end(); ++it){
33
			error(it->code, "bodies->%s", it->text);
34
		}
35
		return false;
36
	}
114 cycrow 37
 
1 cycrow 38
	is >> hdr;
114 cycrow 39
	if(hdr!=HDR_END)
1 cycrow 40
		error(e_badEndHeader);
114 cycrow 41
 
42
	return(hdr==HDR_END && !is.fail());
1 cycrow 43
}
44
//---------------------------------------------------------------------------------
114 cycrow 45
bool bob_dom_bob::toFile(obinaryfilestream& os)
1 cycrow 46
{
114 cycrow 47
	os << HDR_BEGIN;
1 cycrow 48
	info.toFile(os);
49
	materials.toFile(os);
50
	bodies.toFile(os);
114 cycrow 51
	os << HDR_END;
1 cycrow 52
	return os.good();
53
}
54
//---------------------------------------------------------------------------------
114 cycrow 55
bool bob_dom_bob::toFile(otextfilestream& os)
1 cycrow 56
{
57
	info.toFile(os);
58
	os << endl;
59
	materials.toFile(os);
60
	if(materials.size())
61
		os << endl;
114 cycrow 62
	if(bodies.toFile(os, *m_settings, &materials)==false){
63
		for(bob_bodies::ErrorIterator &e_it=bodies.errors.begin(); e_it!=bodies.errors.end(); ++e_it){
64
			error(e_it->severity, e_it->code, "Bodies->%s", e_it->text);
65
		}
66
		return false;
67
	}
1 cycrow 68
	return os.good();
69
}
70
//---------------------------------------------------------------------------------
71
// MATERIAL  - object
114 cycrow 72
bool bob_material1::load(ibinaryfilestream& is)
1 cycrow 73
{
74
	is >> index;
75
	is >> textureID; // int?
76
	is >> ambient;
77
	is >> diffuse;
78
	is >> specular;
114 cycrow 79
 
1 cycrow 80
	errorCode=is.fail() ? e_notEnoughData : e_noError;
114 cycrow 81
 
1 cycrow 82
	return !is.fail();
83
}
84
//---------------------------------------------------------------------------------
114 cycrow 85
bool bob_material1::toFile(obinaryfilestream& os)
1 cycrow 86
{
87
	os << index << textureID << ambient << diffuse << specular;
114 cycrow 88
 
1 cycrow 89
	return os.good();
90
}
91
//---------------------------------------------------------------------------------
114 cycrow 92
bool bob_material1::toFile(otextfilestream& os)
1 cycrow 93
{
94
	os << noSemicolons << "MATERIAL";
95
	switch(type){
96
		case mat3:
97
			os << '3';
98
			break;
99
		case mat5:
100
			os << '5';
101
			break;
102
	}
103
	os << ": " << autoSemicolons;
104
	os << index << textureID;
105
	os << ambient << diffuse << specular;
114 cycrow 106
 
1 cycrow 107
	return os.good();
108
}
109
//---------------------------------------------------------------------------------
110
// MATERIAL 3 - object
114 cycrow 111
bool bob_material3::load(ibinaryfilestream& is)
1 cycrow 112
{
113
	base::load(is);
114
	if(type > mat1){
115
		is >> transparency; // int?
116
		is >> selfIllumination;
117
		is >> shininess;
118
		short s;
119
		is >> s;
120
		destinationBlend = (s & 0x2) > 0;
121
		twoSided = (s & 0x10) > 0;
122
		wireframe = (s & 0x8) > 0;
123
		is >> textureValue;
124
		is >> enviromentMap;
125
		is >> bumpMap;
126
	}
127
	errorCode=is.fail() ? e_notEnoughData : e_noError;
114 cycrow 128
 
1 cycrow 129
	return !is.fail();
130
}
131
//---------------------------------------------------------------------------------
114 cycrow 132
bool bob_material3::toFile(obinaryfilestream& os)
1 cycrow 133
{
134
	base::toFile(os);
135
	os << transparency << selfIllumination << shininess;
136
	short s=0;
137
	if(destinationBlend) s|=0x2;
138
	if(twoSided) s|=0x10;
139
	if(wireframe) s|=0x8;
140
	os << s;
141
	os << textureValue << enviromentMap << bumpMap;
114 cycrow 142
 
1 cycrow 143
	return os.good();
144
}
145
//---------------------------------------------------------------------------------
114 cycrow 146
bool bob_material3::toFile(otextfilestream& os)
1 cycrow 147
{
148
	base::toFile(os);
149
	os << autoSemicolons;
150
	os << transparency << selfIllumination << shininess;
151
	os << noSemicolons << destinationBlend << ';' << twoSided << ';' << autoSemicolons << wireframe;
152
	os << textureValue;
153
	os << enviromentMap << bumpMap;
154
	return os.good();
155
}
156
//---------------------------------------------------------------------------------
157
// MATERIAL5
114 cycrow 158
bool bob_material5::load(ibinaryfilestream& is)
1 cycrow 159
{
160
	base::load(is);
161
	if(type > mat3)
162
		is >> lightMap;
114 cycrow 163
 
1 cycrow 164
	errorCode=is.fail() ? e_notEnoughData : e_noError;
114 cycrow 165
 
1 cycrow 166
	return !is.fail();
167
}
168
//---------------------------------------------------------------------------------
114 cycrow 169
bool bob_material5::toFile(obinaryfilestream& os)
1 cycrow 170
{
171
	base::toFile(os);
172
	os << lightMap;
173
	return os.good();
174
}
175
//---------------------------------------------------------------------------------
114 cycrow 176
bool bob_material5::toFile(otextfilestream& os)
1 cycrow 177
{
178
	base::toFile(os);
179
	if(type > mat3)
180
		os << autoSemicolons << lightMap;
181
	return os.good();
182
}
183
//---------------------------------------------------------------------------------
184
char * material6_value::m_stringTypes[]={
185
	"SPTYPE_LONG",
186
	"SPTYPE_BOOL",
187
	"SPTYPE_FLOAT",
188
	"",
189
	"",
190
	"SPTYPE_FLOAT4",
191
	"",
192
	"",
193
	"SPTYPE_STRING"
194
};
195
 
196
int material6_value::m_stringTypesCount=9;
197
 
114 cycrow 198
bob_error_codes material6_value::load(ibinaryfilestream &is)
1 cycrow 199
{
200
	is >> name;
201
	if(is.fail()) return e_error;
202
	short t;
203
	is >> t;
204
	type=(Type)t;
114 cycrow 205
 
1 cycrow 206
	switch(type){
207
		case typeBool: // no break
208
		case typeLong:
209
			is >> val.i;
210
			break;
211
		case typeFloat:
212
			is >> val.f;
213
			break;
214
		case typeFloat4:
215
			is >> val.f4;
216
			break;
217
		case typeString:
218
			is >> val.psz;
219
			break;
114 cycrow 220
		default:
1 cycrow 221
			return e_unkMaterialValueType;
222
	}
223
	return is.fail() ? e_error : e_noError;
224
}
225
//---------------------------------------------------------------------------------
114 cycrow 226
bool material6_value::toFile(obinaryfilestream& os)
1 cycrow 227
{
228
	os << name << (short) type;
114 cycrow 229
 
1 cycrow 230
	switch(type){
231
		case typeBool: // no break
232
		case typeLong:
233
			os << val.i;
234
			break;
235
		case typeFloat:
236
			os << val.f;
237
			break;
238
		case typeFloat4:
239
			os << val.f4;
240
			break;
241
		case typeString:
242
			os << val.psz;
243
			break;
114 cycrow 244
		default:
1 cycrow 245
			return false;
246
	}
247
	return os.good();
248
}
249
//---------------------------------------------------------------------------------
114 cycrow 250
bool material6_value::toFile(otextfilestream& os)
1 cycrow 251
{
252
	int old=os.flags();
253
	os << noSemicolons << name << ';';
114 cycrow 254
 
1 cycrow 255
	os << typeName() << ';';
114 cycrow 256
 
1 cycrow 257
	switch(type){
258
		case typeLong:
259
			os << val.i << ';';
260
			break;
261
		case typeBool:
262
			os << val.i << ';';
263
			break;
264
		case typeFloat:
265
			os << val.f << ';';
266
			break;
267
		case typeFloat4:
268
			for(int i=0; i < 4; i++){
269
				os << val.f4.f[i] << ';';
270
			}
271
			break;
272
		case typeString:
273
			os << val.psz << ';';
274
			break;
275
		default:
276
			return false;
277
	}
278
	os << ' ';
279
	os.flags(old);
280
	return os.good();
281
}
282
//---------------------------------------------------------------------------------
283
// MATERIAL6_VALUES
114 cycrow 284
bob_error_codes bob_material6_values::load(ibinaryfilestream& is)
1 cycrow 285
{
286
	short count;
287
	material6_value *v;
114 cycrow 288
 
1 cycrow 289
	bob_error_codes res;
114 cycrow 290
 
1 cycrow 291
	is >> count;
292
	for(int i=0; i < count; i++){
293
		v=new material6_value();
294
		if((res=v->load(is))!=e_noError) {
295
			delete v;
296
			return res;
297
		}
298
		push_back(v);
299
	}
300
	return is.fail() ? e_error : e_noError;
301
}
302
//---------------------------------------------------------------------------------
114 cycrow 303
bool bob_material6_values::toFile(obinaryfilestream& os)
1 cycrow 304
{
305
	os << (short)size();
306
	for(iterator &it=begin(); it!=end(); ++it){
307
		it->toFile(os);
308
	}
309
	return os.good();
310
}
311
//---------------------------------------------------------------------------------
114 cycrow 312
bool bob_material6_values::toFile(otextfilestream& os)
1 cycrow 313
{
314
	os << (int)size();
315
	for(iterator &it=begin(); it!=end(); ++it){
316
		it->toFile(os);
317
	}
318
	return os.good();
319
}
320
//---------------------------------------------------------------------------------
321
// MATERIAL6 - big
114 cycrow 322
bob_error_codes bob_material6::Big::load(ibinaryfilestream& is)
1 cycrow 323
{
324
	bob_error_codes errorCode;
114 cycrow 325
 
1 cycrow 326
	is >> technique >> effect;
114 cycrow 327
 
1 cycrow 328
	errorCode=values.load(is);
114 cycrow 329
 
1 cycrow 330
	return errorCode;
331
}
332
//---------------------------------------------------------------------------------
114 cycrow 333
bool bob_material6::Big::toFile(obinaryfilestream& os)
1 cycrow 334
{
335
	os << technique << effect;
336
	values.toFile(os);
337
	return os.good();
338
}
339
//---------------------------------------------------------------------------------
114 cycrow 340
bool bob_material6::Big::toFile(otextfilestream& os)
1 cycrow 341
{
342
	int old=os.flags();
343
	os << autoSemicolons << technique << effect;
344
	values.toFile(os);
345
	os.flags(old);
346
	return os.good();
347
}
348
//---------------------------------------------------------------------------------
349
// MATERIAL 6 - small
114 cycrow 350
bob_error_codes bob_material6::Small::load(ibinaryfilestream& is, int flags)
1 cycrow 351
{
352
	is >> textureFile;
353
	is >> ambient >> diffuse >> specular;
354
	is >> transparency >> selfIllumination >> shininess;
355
	short s=flags;
356
	//is >> s;
357
	destinationBlend = (s & 0x2) > 0;
358
	twoSided = (s & 0x10) > 0;
359
	wireframe = (s & 0x8) > 0;
360
	is >> textureValue >> enviromentMap >> bumpMap >> lightMap;
361
	is >> map4 >> map5;
114 cycrow 362
 
1 cycrow 363
	return !is.fail() ? e_noError : e_notEnoughData;
364
}
365
//---------------------------------------------------------------------------------
114 cycrow 366
bool bob_material6::Small::toFile(obinaryfilestream& os)
1 cycrow 367
{
368
	static char *empty="";
369
	os << (textureFile ? textureFile : empty);
370
	os << ambient << diffuse << specular;
371
	os << transparency << selfIllumination << shininess;
114 cycrow 372
 
1 cycrow 373
	os << textureValue << enviromentMap << bumpMap << lightMap;
374
	os << map4 << map5;
114 cycrow 375
 
1 cycrow 376
	return os.good();
377
}
378
//---------------------------------------------------------------------------------
114 cycrow 379
bool bob_material6::Small::toFile(otextfilestream& os)
1 cycrow 380
{
381
	os << (*textureFile==0 ? "NULL" : textureFile);
382
	os << ambient << diffuse << specular;
383
	os << transparency << selfIllumination << shininess;
384
	os << noSemicolons << destinationBlend << ';' << twoSided << ';' << autoSemicolons << wireframe;
385
	os << textureValue;
386
	os << enviromentMap << bumpMap << lightMap << map4 << map5;
387
	return os.good();
388
}
389
//---------------------------------------------------------------------------------
390
// MATERIAL 6
114 cycrow 391
bool bob_material6::load(ibinaryfilestream& is)
1 cycrow 392
{
393
	is >> index;
394
	is >> flags;
114 cycrow 395
 
1 cycrow 396
	if(flags==Big::flag) {
397
		big=new Big();
398
		errorCode=big->load(is);
399
	}
400
	else{
401
		/*FILE *f=fopen("d:\\mat56.log", "a+");
402
		fprintf(f, "%s - flags: %d, offset 0x%x\n", is.name(), flags, is.tell());
403
		fclose(f);
404
		*/
114 cycrow 405
 
1 cycrow 406
		small=new Small();
407
		errorCode=small->load(is, flags);
408
	}
114 cycrow 409
 
1 cycrow 410
	return errorCode==e_noError;
411
}
412
//---------------------------------------------------------------------------------
114 cycrow 413
bool bob_material6::toFile(obinaryfilestream& os)
1 cycrow 414
{
415
	bool bRes;
114 cycrow 416
 
1 cycrow 417
	os << index << flags;
418
	if(big)
419
		bRes=big->toFile(os);
420
	else
421
		bRes=small->toFile(os);
114 cycrow 422
 
1 cycrow 423
	return bRes;
424
}
425
//---------------------------------------------------------------------------------
114 cycrow 426
bool bob_material6::toFile(otextfilestream& os)
1 cycrow 427
{
428
	int old=os.flags();
114 cycrow 429
	os << noSemicolons << "MATERIAL6: "
1 cycrow 430
	<< autoSemicolons << index << noSemicolons << "0x" << hex << autoSemicolons << flags << dec;
114 cycrow 431
 
432
	if(big)
1 cycrow 433
		big->toFile(os);
434
	else if(small)
435
		small->toFile(os);
114 cycrow 436
 
1 cycrow 437
	os.flags(old);
438
	return os.good();
439
}
440
//---------------------------------------------------------------------------------
441
// MATERIAL - section
114 cycrow 442
bool bob_materials::load(ibinaryfilestream& is)
1 cycrow 443
{
444
	int hdr;
114 cycrow 445
	bob_material::materialType type;
446
 
447
	is >> hdr;
1 cycrow 448
 
449
	switch(hdr){
114 cycrow 450
		case HDR_MAT5_BEGIN:
451
			type=bob_material::mat5;
1 cycrow 452
			break;
114 cycrow 453
		case HDR_MAT6_BEGIN:
454
			type=bob_material::mat6;
1 cycrow 455
			break;
456
		default:
457
			error(e_badHeader);
458
			return false;
459
	}
114 cycrow 460
 
1 cycrow 461
	int matCount;
462
	is >> matCount;
463
 
114 cycrow 464
	bob_material *m;
1 cycrow 465
	for(int i=0; i < matCount; i++){
466
		switch(type) {
114 cycrow 467
			case bob_material::mat5:
468
				m=new bob_material5();
1 cycrow 469
				break;
114 cycrow 470
			case bob_material::mat6:
471
				m=new bob_material6();
1 cycrow 472
				break;
473
		}
474
		if(m->load(is)==false){
475
			error(m->errorCode, "material[%d]: %s", i, bob_traslate_error(m->errorCode));
476
			delete m;
477
			return false;
478
		}
479
		else
480
			push_back(m);
481
	}
482
	is >> hdr;
114 cycrow 483
	if(hdr!=HDR_END)
1 cycrow 484
		error(e_badEndHeader);
114 cycrow 485
 
486
	return (hdr==HDR_END && !is.fail());
1 cycrow 487
}
488
//---------------------------------------------------------------------------------
114 cycrow 489
bool bob_materials::toFile(obinaryfilestream& os)
1 cycrow 490
{
491
	int hdr;
114 cycrow 492
	if(size() && front()->type==bob_material::mat6)
493
		hdr=HDR_MAT6_BEGIN;
1 cycrow 494
	else
114 cycrow 495
		hdr=HDR_MAT5_BEGIN;
496
 
1 cycrow 497
	os << hdr << (int)size();
498
	for(iterator &it=begin(); it!=end(); ++it){
499
		it->toFile(os);
500
	}
114 cycrow 501
	os << HDR_END;
1 cycrow 502
	return os.good();
503
}
504
//---------------------------------------------------------------------------------
114 cycrow 505
bool bob_materials::toFile(otextfilestream& os)
1 cycrow 506
{
507
	for(iterator &it=begin(); it!=end(); ++it){
508
		it->toFile(os);
509
		os << endl;
510
	}
511
	return os.good();
512
}
513
//---------------------------------------------------------------------------------
514
// BODIES - section
114 cycrow 515
bool bob_bodies::load(ibinaryfilestream& is)
1 cycrow 516
{
517
	int hdr;
518
	is >> hdr;
114 cycrow 519
	if(hdr!=HDR_BEGIN){
1 cycrow 520
		error(e_badHeader);
521
		return false;
522
	}
523
	short bodyCount;
524
	is >> bodyCount;
114 cycrow 525
 
1 cycrow 526
	child_type *ch;
527
	for(int i=0; i < bodyCount; i++){
528
		ch=createChild();
529
		if(ch->load(is)==false){
530
			for(ErrorIterator &it=ch->errors.begin(); it!=ch->errors.end(); ++it){
531
				error(it->code, "body[%d]->%s", i, it->text);
532
			}
533
			return false;
534
		}
535
	}
114 cycrow 536
 
1 cycrow 537
	is >> hdr;
538
	if(is.fail())
539
		error(e_notEnoughData);
114 cycrow 540
 
541
	if(hdr!=HDR_END)
1 cycrow 542
		error(e_badEndHeader);
114 cycrow 543
 
544
	return hdr==HDR_END;
1 cycrow 545
}
546
//---------------------------------------------------------------------------------
114 cycrow 547
bool bob_bodies::toFile(obinaryfilestream& os)
1 cycrow 548
{
114 cycrow 549
	os << HDR_BEGIN << (short)size();
1 cycrow 550
	for(iterator &it=begin(); it!=end(); ++it){
551
		it->toFile(os);
552
	}
114 cycrow 553
	os << HDR_END;
1 cycrow 554
	return os.good();
555
}
556
//---------------------------------------------------------------------------------
114 cycrow 557
bool bob_bodies::toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials)
1 cycrow 558
{
559
	int i=1;
560
	os << noSemicolons << "// beginning of bodies (" << (int)size() << ')' << endl;
561
	for(iterator &it=begin(); it!=end(); ++it, ++i){
114 cycrow 562
		if(it->toFile(os, settings, materials, i)==false){
563
			for(bob_body::ErrorIterator &e_it=it->errors.begin(); e_it!=it->errors.end(); ++e_it){
564
				error(e_it->severity, e_it->code, "Body[%d]->%s", i, e_it->text);
565
			}
566
			return false;
567
		}
1 cycrow 568
		os << endl;
569
	}
570
	os << "// end of bodies" << endl;
114 cycrow 571
	return os.good();
1 cycrow 572
}
573
//---------------------------------------------------------------------------------
574
// POINTS - section
114 cycrow 575
bool bob_vertices::load(ibinaryfilestream& is)
1 cycrow 576
{
577
	int hdr;
578
	is >> hdr;
114 cycrow 579
	if(hdr!=HDR_BEGIN){
1 cycrow 580
		error(e_badHeader);
581
		return false;
582
	}
114 cycrow 583
 
1 cycrow 584
	int pointCount;
585
	is >> pointCount;
114 cycrow 586
 
1 cycrow 587
	map.create(pointCount);
114 cycrow 588
 
589
	bob_vertex *ch;
1 cycrow 590
	for(int i=0; i < pointCount; i++){
114 cycrow 591
		ch=new bob_vertex();
1 cycrow 592
		if(ch->load(is)==false){
593
			error(ch->errorCode, "point[%d]: %s", i, bob_traslate_error(ch->errorCode));
594
			delete ch;
595
			return false;
596
		}
597
		map.addPoint(ch);
114 cycrow 598
 
1 cycrow 599
	}
114 cycrow 600
 
1 cycrow 601
	is >> hdr;
114 cycrow 602
	if(hdr!=HDR_END)
1 cycrow 603
		error(e_badEndHeader);
114 cycrow 604
 
605
	return hdr==HDR_END && !is.fail();
1 cycrow 606
}
607
//---------------------------------------------------------------------------------
114 cycrow 608
bool bob_vertices::toFile(obinaryfilestream& os)
1 cycrow 609
{
114 cycrow 610
	os << HDR_BEGIN;
611
 
612
	if(new_vertices.size()){
613
		os << (int)new_vertices.size();
614
		for(VertexIterator &it=new_vertices.begin(); it!=new_vertices.end(); ++it){
1 cycrow 615
			it->toFile(os);
616
		}
617
	}
618
	else{
619
		os << (int)map.pointsSize();
620
		for(bob_point_map::iterator &it=map.begin(); it!=map.end(); ++it){
621
			it->toFile(os);
622
		}
623
	}
114 cycrow 624
	os << HDR_END;
1 cycrow 625
	return os.good();
626
}
627
//---------------------------------------------------------------------------------
114 cycrow 628
bool bob_vertices::toFile(otextfilestream& os, const Settings& settings)
1 cycrow 629
{
114 cycrow 630
	if(settings.rawMode())
631
		return outputRaw(os);
632
	else
633
		return outputBOD(os);
634
}
635
//---------------------------------------------------------------------------------
636
bool bob_vertices::outputBOD(otextfilestream& os)
637
{
1 cycrow 638
	int oldf=os.flags();
639
	int i=0;
640
	os << noSemicolons << "// beginning of points (" << (int)map.uniquePointsSize() << ')' << endl << autoSemicolons;
114 cycrow 641
 
642
	bob_vertex *p;
1 cycrow 643
	while(p=map.nextUniquePoint()){
644
		p->toFile(os, i++);
645
	}
114 cycrow 646
 
1 cycrow 647
	os << noSemicolons << "-1; -1; -1; // points end" << endl << endl;
114 cycrow 648
 
649
	os.flags(oldf);
650
	return os.good();
651
}
652
//---------------------------------------------------------------------------------
653
bool bob_vertices::outputRaw(otextfilestream& os)
654
{
655
	int oldf=os.flags();
656
	int i=0;
657
 
658
	os << noSemicolons << "// Vertices begin (" << (int)map.pointsSize() << " - " << (int)map.uniquePointsSize() << " unique)" << endl << autoSemicolons;
659
	for(bob_point_map::iterator &it=map.begin(); it!=map.end(); ++it, i++){
660
		os << autoSemicolons
661
		<< it->x << it->y << it->z;
662
 
663
		if(it->hasTextureCoords()){
664
			os << noSemicolons << "\t\tUV: " << autoSemicolons
665
			<< it->textureCoords.x << it->textureCoords.y;
666
		}
667
 
668
		if(it->flags & bob_vertex::FLAG_WEIRD_STUFF){
669
			os << noSemicolons << "\tWeird coords: " << autoSemicolons
670
			<< it->weirdCoords.x << it->weirdCoords.y;
671
		}
672
 
673
		os << noSemicolons << "\tNormal: " << autoSemicolons
674
		<< it->normalVector.x << it->normalVector.y << it->normalVector.z
675
		<< noSemicolons << "\tSGBits: " << it->sgbits;
676
 
677
		os << noSemicolons << " // " << i << endl;
678
	}
679
 
680
	os << noSemicolons << "-1; -1; -1; // Vertices end" << endl << endl;
1 cycrow 681
 
682
	os.flags(oldf);
683
	return os.good();
684
}
685
//---------------------------------------------------------------------------------
686
// POINT - object
114 cycrow 687
bool bob_vertex::load(ibinaryfilestream& is)
688
{
689
	/*
690
		possible types
691
		0x1F - normal + UV + 2 unk values
692
		0x1B - normal + UV
693
		0x19 - normal
694
	*/
1 cycrow 695
 
114 cycrow 696
	is >> flags >> *(vertex*)this;
1 cycrow 697
 
114 cycrow 698
	if((flags & FLAG_DEFAULT)!=FLAG_DEFAULT){
699
		errorCode=e_unkPointFlags;
700
		return false;
1 cycrow 701
	}
114 cycrow 702
 
703
	if(hasTextureCoords())
704
		is >> textureCoords;
1 cycrow 705
 
114 cycrow 706
	if(flags & FLAG_WEIRD_STUFF)
707
		is >> weirdCoords;
708
 
709
	is >> normalVector >> sgbits;
710
 
1 cycrow 711
	if(is.fail())
712
		errorCode=e_notEnoughData;
114 cycrow 713
 
1 cycrow 714
	return !is.fail();
715
}
716
//---------------------------------------------------------------------------------
114 cycrow 717
bool bob_vertex::toFile(obinaryfilestream& os)
1 cycrow 718
{
114 cycrow 719
	// set the default bits before outputting
720
	flags|=FLAG_DEFAULT;
721
 
722
	os << flags << *(dynamic_cast<vertex*>(this));
723
	if(hasTextureCoords())
724
		os << textureCoords;
725
 
726
	if(flags & FLAG_WEIRD_STUFF)
727
		os << weirdCoords;
728
 
729
	os << normalVector << sgbits;
730
 
1 cycrow 731
	return os.good();
732
}
733
//---------------------------------------------------------------------------------
114 cycrow 734
bool bob_vertex::toFile(otextfilestream& os, int idx)
1 cycrow 735
{
736
	// autoSemicolons is set by parent (points)
114 cycrow 737
 
738
	int coords[3];
739
	getBodCoords(coords);
740
 
741
	os << coords[0] << coords[1] << coords[2];
742
 
1 cycrow 743
	os << noSemicolons << "// " << idx << endl << autoSemicolons;
744
	return os.good();
745
}
746
//---------------------------------------------------------------------------------
114 cycrow 747
// X3 vertex_data_record
748
bool bob_x3vertex_data_record::load(ibinaryfilestream& is)
1 cycrow 749
{
114 cycrow 750
	is >> pointIndex >> tangent >> unk;
1 cycrow 751
	return !is.fail();
752
}
753
//---------------------------------------------------------------------------------
114 cycrow 754
bool bob_x3vertex_data_record::toFile(obinaryfilestream& os)
1 cycrow 755
{
114 cycrow 756
	os << pointIndex << tangent << unk;
1 cycrow 757
	return os.good();
758
}
759
//---------------------------------------------------------------------------------
114 cycrow 760
/*int compare_x3vertex_rec(const void *a, const void *b)
1 cycrow 761
{
114 cycrow 762
	const bob_x3vertex_data_record *rec1=*((bob_x3vertex_data_record**)a), *rec2=*((bob_x3vertex_data_record**)b);
763
	return rec1->pointIndex - rec2->pointIndex;
764
}*/
1 cycrow 765
//---------------------------------------------------------------------------------
766
// X3 uv list
114 cycrow 767
bool bob_x3vertex_data::load(ibinaryfilestream& is)
1 cycrow 768
{
769
	int count;
114 cycrow 770
	bob_x3vertex_data_record *rec;
771
 
1 cycrow 772
	is >> count;
773
	reserve(count);
774
	for(int i=0; i < count; i++){
114 cycrow 775
		rec=new bob_x3vertex_data_record();
776
		if(!rec->load(is)){
777
			delete rec;
1 cycrow 778
			return false;
779
		}
114 cycrow 780
		push_back(rec);
1 cycrow 781
	}
114 cycrow 782
 
783
	/* 
784
		there should never be the need to compare the data, because they are written in the order of vertices,
785
		and thus their vertex indexes are always in sequence
786
	*/
787
	//sort(compare_x3vertex_rec);
788
 
1 cycrow 789
	return !is.fail();
790
}
791
//---------------------------------------------------------------------------------
114 cycrow 792
bool bob_x3vertex_data::toFile(obinaryfilestream& os)
1 cycrow 793
{
794
	os << (int) size();
795
	for(iterator &it=begin(); it!=end(); ++it){
796
		it->toFile(os);
797
	}
798
	return os.good();
799
}
800
//---------------------------------------------------------------------------------
801
 
802
// FACE LIST
114 cycrow 803
bool bob_face_list::load(ibinaryfilestream& is, bool x3data)
1 cycrow 804
{
805
	int count;
114 cycrow 806
 
1 cycrow 807
	is >> materialIndex >> count;
114 cycrow 808
 
1 cycrow 809
	for(int i=0; i < count; i++){
114 cycrow 810
		bob_face *face=new bob_face();
1 cycrow 811
		if(face->load(is)==false){
812
			error(face->errorCode, "face[%d]: %s", i, bob_traslate_error(face->errorCode));
813
			delete face;
814
			return false;
815
		}
816
		push_back(face);
817
	}
114 cycrow 818
 
819
	if(x3data && x3vertexData.load(is)==false) return false;
820
 
1 cycrow 821
	return !is.fail();
822
}
823
//---------------------------------------------------------------------------------
114 cycrow 824
bool bob_face_list::toFile(obinaryfilestream& os, const bob_vertices& vertices, bool x3data)
1 cycrow 825
{
826
	os << materialIndex << (int)size();
827
	for(iterator &it=begin(); it!=end(); ++it){
828
		it->toFile(os);
829
	}
114 cycrow 830
 
1 cycrow 831
	if(x3data)
114 cycrow 832
		saveVertexTangents(os, vertices);
833
 
834
	return os.good();
835
}
836
//---------------------------------------------------------------------------------
837
bool bob_face_list::saveVertexTangents(obinaryfilestream& os, const bob_vertices& vertices)
838
{
839
	// the still unknown God damned vector
840
	vector vec1(0,0,1); // default value
841
	vector vec0(0,0,0); // zero value
1 cycrow 842
 
114 cycrow 843
	bool *vert_map=new bool[vertices.new_vertices.size()];
844
	memset(vert_map, 0, vertices.new_vertices.size() * sizeof(bool));
845
 
846
	size_t count_pos=os.tell();
847
	os << 123; // dummy count
848
 
849
	int idx, count=0;
850
	for(iterator &it=begin(); it!=end(); ++it){
851
		for(int i=0; i < 3; i++){
852
			idx=it->values[i];
853
			if(vert_map[idx]==false) {
854
				vector &tan=vertices.new_vertices[idx]->tangentVector;
855
				os << idx << tan << (tan.isZero() ? vec0 : vec1);
856
				vert_map[idx]=true;
857
				count++;
858
			}
859
		}
860
	}
861
	delete[] vert_map;
862
 
863
	// write the real count
864
	size_t lastp=os.tell();
865
	os.seek((int)count_pos, mystream::stream_base::seek_begin);
866
	os << count;
867
	os.seek((int)lastp, mystream::stream_base::seek_begin);
868
 
1 cycrow 869
	return os.good();
870
}
871
//---------------------------------------------------------------------------------
114 cycrow 872
bool bob_face_list::outputX3VertexDataRaw(otextfilestream& os)
873
{
874
	if(x3vertexData.size()==0) return true;
875
 
876
	int old=os.flags();
877
	os << noSemicolons << "// Material " << materialIndex << endl;
878
	os << "// Material; point index; tangent; unknown" << endl << autoSemicolons;
879
	for(bob_x3vertex_data::const_iterator &it=x3vertexData.begin(); it!=x3vertexData.end(); ++it){
880
		os << materialIndex << it->pointIndex << it->tangent << it->unk << endl;
881
	}
882
	os << endl;
883
	os.flags(old);
884
	return os.good();
885
}
886
//---------------------------------------------------------------------------------
887
/*
888
bool bob_face_list::computeAndOutputTangents(otextfilestream& os, const bob_point_map& pointMap)
889
{
890
	vertex v1, v2, v3;
891
	geometry::point2d<double> w1,w2,w3;
892
	int i1,i2,i3;
893
 
894
	vector *tan1, *tan2;
895
 
896
	tan1=new vector[pointMap.pointsSize() * 2];
897
	tan2=tan1 + pointMap.pointsSize();
898
 
899
	for(iterator &it=begin(); it!=end(); ++it){
900
 
901
		i1=it->values[0]; i2=it->values[1]; i3=it->values[2];
902
		v1=*pointMap[i1];
903
		v2=*pointMap[i2];
904
		v3=*pointMap[i3];
905
 
906
		w1=pointMap[i1]->textureCoords;
907
		w2=pointMap[i2]->textureCoords;
908
		w3=pointMap[i3]->textureCoords;
909
 
910
		double x1 = v2.x - v1.x;
911
    double x2 = v3.x - v1.x;
912
    double y1 = v2.y - v1.y;
913
    double y2 = v3.y - v1.y;
914
    double z1 = v2.z - v1.z;
915
    double z2 = v3.z - v1.z;
916
 
917
    double s1 = w2.x - w1.x;
918
    double s2 = w3.x - w1.x;
919
    double t1 = w2.y - w1.y;
920
    double t2 = w3.y - w1.y;
921
 
922
    double cp=s1 * t2 - s2 * t1;
923
 
924
    if(cp!=0) {
925
			double r = 1.0 / cp;
926
			vector sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
927
							(t2 * z1 - t1 * z2) * r);
928
			vector tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
929
							(s1 * z2 - s2 * z1) * r);
930
 
931
			tan1[i1] += sdir;
932
			tan1[i2] += sdir;
933
			tan1[i3] += sdir;
934
 
935
			tan2[i1] += tdir;
936
			tan2[i2] += tdir;
937
			tan2[i3] += tdir;
938
		}
939
	}
940
 
941
	int oldf=os.flags();
942
 
943
	os << noSemicolons << "// vertex tangents" << autoSemicolons << endl;
944
 
945
	int i=0;
946
	for(bob_point_map::const_iterator &it=pointMap.begin(); it!=pointMap.end(); ++it, i++){
947
		const vector& n=it->normalVector;
948
		const vector& t=tan1[i];
949
		const vector& bt=tan2[i];
950
 
951
		// Gram-Schmidt orthogonalize
952
		vector tangent = (t - n * n.dot(t)).normalize();
953
 
954
		os << i << tangent << endl;
955
 
956
	}
957
 
958
	delete[] tan1;
959
 
960
	os.flags(oldf);
961
 
962
	return os.good();
963
}*/
964
//---------------------------------------------------------------------------------
1 cycrow 965
// PARTS - section PART
114 cycrow 966
bool bob_parts::load(ibinaryfilestream& is)
1 cycrow 967
{
968
	int hdr, count;
114 cycrow 969
 
1 cycrow 970
	is >> hdr;
114 cycrow 971
	if(hdr!=HDR_BEGIN){
1 cycrow 972
		error(e_badHeader);
973
		return false;
974
	}
114 cycrow 975
 
1 cycrow 976
	is >> count;
114 cycrow 977
 
978
	bob_part *part;
1 cycrow 979
	for(int i=0; i < count; i++){
114 cycrow 980
		part=new bob_part();
1 cycrow 981
		if(!part->load(is)){
982
			for(ErrorIterator &it=part->errors.begin(); it!=part->errors.end(); ++it){
983
				error(it->severity, it->code, "part[%d]->%s", i, it->text);
984
			}
985
			delete part;
986
			return false;
987
		}
988
		push_back(part);
989
	}
990
 
991
	is >> hdr;
114 cycrow 992
	if(hdr!=HDR_END)
1 cycrow 993
		error(e_badEndHeader);
114 cycrow 994
 
995
	return hdr==HDR_END && !is.fail();
1 cycrow 996
}
997
//---------------------------------------------------------------------------------
114 cycrow 998
bool bob_parts::toFile(obinaryfilestream& os, const bob_vertices& vertices)
1 cycrow 999
{
114 cycrow 1000
	os << HDR_BEGIN << (int) size();
1 cycrow 1001
	for(iterator &it=begin(); it!=end(); ++it){
114 cycrow 1002
		it->toFile(os, vertices);
1 cycrow 1003
	}
114 cycrow 1004
	os << HDR_END;
1005
 
1 cycrow 1006
	return os.good();
1007
}
1008
//---------------------------------------------------------------------------------
114 cycrow 1009
bool bob_parts::toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map *pointMap)
1 cycrow 1010
{
1011
	int i=1;
1012
	for(iterator &it=begin(); it!=end(); ++it, ++i){
114 cycrow 1013
		if(it->toFile(os, settings, materials, *pointMap, i)==false){
1014
			for(bob_part::ErrorIterator &e_it=it->errors.begin(); e_it!=it->errors.end(); ++e_it){
1015
				error(e_it->severity, e_it->code, "Part[%d]->%s", i, e_it->text);
1016
			}
1017
			return false;
1018
		}
1 cycrow 1019
	}
1020
	return os.good();
1021
}
1022
//---------------------------------------------------------------------------------
114 cycrow 1023
bool bob_part_collision_box::load(ibinaryfilestream& is)
1 cycrow 1024
{
114 cycrow 1025
	is >> sphereOffset >> sphereDiameter;
1026
	is >> boxOffset >> boxSize;
1027
 
1 cycrow 1028
	return !is.fail();
1029
}
1030
//---------------------------------------------------------------------------------
114 cycrow 1031
bool bob_part_collision_box::toFile(obinaryfilestream& os)
1 cycrow 1032
{
114 cycrow 1033
	os << sphereOffset << sphereDiameter;
1034
	os << boxOffset << boxSize;
1 cycrow 1035
	return os.good();
1036
}
1037
//---------------------------------------------------------------------------------
114 cycrow 1038
bool bob_part_collision_box::toFile(otextfilestream& os)
1 cycrow 1039
{
1040
	int old=os.flags();
114 cycrow 1041
 
1 cycrow 1042
	os << noSemicolons;
114 cycrow 1043
	os << "/! COLLISION_BOX: " << autoSemicolons;
1 cycrow 1044
 
114 cycrow 1045
	os << boxOffset.x << boxOffset.y << boxOffset.z;
1046
	os << sphereDiameter << boxSize.x << boxSize.y << boxSize.z;
1 cycrow 1047
 
114 cycrow 1048
	os << noSemicolons << "!/" << autoSemicolons << endl;
1049
 
1 cycrow 1050
	os.flags(old);
1051
	return os.good();
1052
}
1053
//---------------------------------------------------------------------------------
1054
// PARTS - object
1055
 
114 cycrow 1056
bool bob_part::load(ibinaryfilestream& is)
1 cycrow 1057
{
1058
	short count;
114 cycrow 1059
 
1 cycrow 1060
 	is >> flags >> count;
114 cycrow 1061
 
1 cycrow 1062
	for(int i=0; i < count; i++){
1063
		bob_face_list *faces=new bob_face_list();
114 cycrow 1064
		if(faces->load(is, (flags & FLAG_X3) > 0)==false){
1 cycrow 1065
			for(ErrorIterator &it=faces->errors.begin(); it!=faces->errors.end(); ++it){
1066
				error(it->severity, it->code, "face list[%d]->%s", i, it->text);
1067
			}
1068
			delete faces;
1069
			return false;
1070
		}
1071
		push_back(faces);
1072
	}
1073
 
114 cycrow 1074
	if(flags & FLAG_X3)
1075
		collisionBox.load(is);
1076
 
1 cycrow 1077
	return !is.fail();
1078
}
1079
//---------------------------------------------------------------------------------
114 cycrow 1080
bool bob_part::toFile(obinaryfilestream& os, const bob_vertices& vertices)
1 cycrow 1081
{
1082
	os << flags << (short)size();
114 cycrow 1083
 
1 cycrow 1084
	for(iterator &it=begin(); it!=end(); ++it){
114 cycrow 1085
		it->toFile(os, vertices, (flags & FLAG_X3) > 0);
1 cycrow 1086
	}
1087
 
114 cycrow 1088
	if(flags & FLAG_X3)
1089
		collisionBox.toFile(os);
1090
 
1 cycrow 1091
	return os.good();
1092
}
1093
//---------------------------------------------------------------------------------
114 cycrow 1094
bool bob_part::toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map& pointMap, int idx)
1 cycrow 1095
{
114 cycrow 1096
	if(settings.rawMode())
1097
		return outputRaw(os, pointMap, idx);
1098
	else
1099
		return outputBOD(os, settings, materials, pointMap, idx);
1100
}
1101
//---------------------------------------------------------------------------------
1102
bool bob_part::outputBOD(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map& pointMap, int idx)
1103
{
1104
	bob_face *face;
1105
	const bob_vertex *pnt;
1 cycrow 1106
	int line=0;
1107
	int materialIndex;
114 cycrow 1108
 
1 cycrow 1109
	int oldf=os.flags();
114 cycrow 1110
 
1111
	os << noSemicolons << "// ----- part " << idx << " (" << (int)numFaces() << " faces) -----" << endl << autoSemicolons;
1112
	for(iterator &facelist_it=begin(); facelist_it!=end(); ++facelist_it){
1113
		materialIndex=facelist_it->materialIndex;
1114
 
1115
		for(bob_face_list::iterator &face_it=facelist_it->begin(); face_it!=facelist_it->end(); ++face_it, ++line){
1116
			face=*face_it;
1117
 
1 cycrow 1118
			os << autoSemicolons << materialIndex;
1119
			for(int i=0; i < 3; i++){
114 cycrow 1120
				os << pointMap.uniqueIndex(face->values[i]);
1 cycrow 1121
			}
114 cycrow 1122
 
1123
			pnt=pointMap[face->values[0]];
1 cycrow 1124
			if(pnt==NULL){
1125
				error(e_pointNotFound);
1126
				return false;
1127
			}
114 cycrow 1128
			int SGBits=pnt->sgbits;
1129
			int magic = 1; // bit 1 is always set
1130
 
1 cycrow 1131
			/*
1132
				meaning of "magic" number:
1133
				-25: smoothing bits and UV coords
1134
				-17: smoothing bits and no UV coords
1135
				-9: no smoothing and UV coords
1136
				-1: no smoothing and no UV coords
114 cycrow 1137
 
1 cycrow 1138
				--obsolete----------------------
1139
				old text from Checker's sources:
1140
				if there are no materials used, magic is -17
1141
				if there are materials and last value of the first point is non zero,
1142
				magic is -25, otherwise it's -9
1143
			*/
114 cycrow 1144
 
1145
			const bob_vertex *points_ar[3];
1 cycrow 1146
			for(int i=0; i < 3; i++){
114 cycrow 1147
				pnt=pointMap[face->values[i]];
1 cycrow 1148
				if(pnt==NULL){
1149
					error(e_pointNotFound);
1150
					return false;
1151
				}
1152
				points_ar[i]=pnt;
1153
			}
114 cycrow 1154
 
1 cycrow 1155
			bool bHasUV=false;
1156
			for(int i=0; i < 3; i++){
114 cycrow 1157
				if(bHasUV=points_ar[i]->hasTextureCoords())
1 cycrow 1158
					break;
1159
			}
114 cycrow 1160
 
1161
			if(bHasUV)
1162
				magic|=BOD_FLAG_UV;
1163
			if(SGBits)
1164
				magic|=BOD_FLAG_SGBITS;
1165
 
1166
			os << (magic * -1);
1167
			if(SGBits!=0)
1168
				os << SGBits;
1169
 
1170
			// we have uv coords, lets output them
1 cycrow 1171
			if(bHasUV){
1172
				for(int i=0; i < 3; i++){
114 cycrow 1173
 
1174
					os << points_ar[i]->textureCoords; // correct output
1 cycrow 1175
				}
1176
 
114 cycrow 1177
				os << noSemicolons << "/! ";
1178
 
1179
				outputNormals(os, points_ar);
1180
 
1181
				if(settings.extraPntInfo())
1182
					outputExtraPtInfo(os, points_ar);
1183
 
1184
				os << noSemicolons << "!/ ";
1 cycrow 1185
			}
1186
			os << noSemicolons << "// " << line << endl;
1187
		}
1188
	}
114 cycrow 1189
 
1 cycrow 1190
	// x3 data
114 cycrow 1191
	if(flags & FLAG_X3){
1192
		collisionBox.toFile(os);
1 cycrow 1193
	}
1194
 
1195
	int bit=1;
1196
	char str[21];
1197
	for(int i=19; i >= 0; i--){
1198
		str[i]=flags & bit ? '1' : '0';
1199
		bit<<=1;
1200
	}
1201
	str[sizeof(str)-1]=0;
114 cycrow 1202
 
1 cycrow 1203
	os << autoSemicolons  << "-99" << str << noSemicolons << "// part " << idx << " end" << endl;
114 cycrow 1204
 
1205
	os.flags(oldf);
1206
 
1207
	return os.good();
1208
}
1209
//---------------------------------------------------------------------------------
1210
bool bob_part::outputX3VertexData(otextfilestream& os, const bob_point_map& pointMap)
1211
{
1212
	int old=os.flags();
1 cycrow 1213
 
114 cycrow 1214
	os << endl << noSemicolons 
1215
	<< "// X3 vertex data (tangent and <unknown>)" << endl
1216
	<< autoSemicolons;
1217
 
1218
	int i=1;
1219
	for(iterator &facelist_it=begin(); facelist_it!=end(); ++facelist_it, i++){
1220
		facelist_it->outputX3VertexDataRaw(os);
1221
 
1222
		//facelist_it->computeAndOutputTangents(os, pointMap);
1223
	}
1224
	os.flags(old);
1225
 
1226
	return true;
1227
}
1228
//---------------------------------------------------------------------------------
1229
void bob_part::outputNormals(otextfilestream& os, const bob_vertex *points[])
1230
{
1231
	int oldf=os.flags();
1232
	bool bSame=true;
1233
	for(int i=1; i < 3; i++){
1234
		bSame&=points[i]->normalVector == points[i - 1]->normalVector;
1235
	}
1236
 
1237
	os << noSemicolons << "N: { " << autoSemicolons;
1238
 
1239
	for(int i=0; i < (bSame ? 1 : 3); i++){
1240
		os << points[i]->normalVector;
1241
	}
1242
	os << noSemicolons << "} ";
1 cycrow 1243
	os.flags(oldf);
114 cycrow 1244
}
1245
//---------------------------------------------------------------------------------
1246
// those are the unknown values stored in point after texture coordinates
1247
// I place them after bod part definition and behind comment, so they are invisible to
1248
// bod viewer and x2
1249
void bob_part::outputExtraPtInfo(otextfilestream& os, const bob_vertex *points[])
1250
{
1251
	int oldf=os.flags();
1252
 
1253
	bool bInfo=false;
1254
	for(int i=0; i < 3; i++){
1255
		bInfo|=(points[i]->flags & bob_vertex::FLAG_WEIRD_STUFF) > 0;
1256
	}
1257
	if(bInfo==false) return;
1 cycrow 1258
 
114 cycrow 1259
	os << noSemicolons << "XPINFO: ";
1260
	for(int i=0; i < 3; i++){
1261
		os << noSemicolons << "{ " << autoSemicolons
1262
		<< points[i]->weirdCoords
1263
		<< noSemicolons << "} ";
1264
	}
1265
	os.flags(oldf);
1 cycrow 1266
}
1267
//---------------------------------------------------------------------------------
1268
// PART - object
114 cycrow 1269
bool bob_face::load(ibinaryfilestream& is)
1 cycrow 1270
{
114 cycrow 1271
	for(int i=0; i < 3; i++){
1 cycrow 1272
		is >> values[i];
1273
	}
114 cycrow 1274
	is >> flags;
1275
 
1276
	if(is.fail())
1 cycrow 1277
		errorCode=e_notEnoughData;
114 cycrow 1278
 
1 cycrow 1279
	return !is.fail();
1280
}
1281
//---------------------------------------------------------------------------------
114 cycrow 1282
bool bob_face::toFile(obinaryfilestream& os)
1 cycrow 1283
{
114 cycrow 1284
	for(int i=0; i < 3; i++){
1 cycrow 1285
		os << values[i];
1286
	}
114 cycrow 1287
	os << flags;
1 cycrow 1288
	return os.good();
1289
}
1290
//---------------------------------------------------------------------------------
114 cycrow 1291
bool bob_body::load(ibinaryfilestream& is)
1 cycrow 1292
{
1293
	is >> bodySize >> bodyFlags;
114 cycrow 1294
	if(peek(is)==bob_bones::HDR_BEGIN){
1 cycrow 1295
		if(!bones.load(is)){
1296
			for(ErrorIterator &it=bones.errors.begin(); it!=bones.errors.end(); ++it){
1297
				error(it->code, "bones: %s", it->text);
1298
			}
1299
			return false;
1300
		}
1301
	}
114 cycrow 1302
	if(peek(is)==bob_vertices::HDR_BEGIN){
1303
		if(vertices.load(is)==false){
1304
			for(ErrorIterator &it=vertices.errors.begin(); it!=vertices.errors.end(); ++it){
1305
				error(it->code, "vertices->%s", it->text);
1 cycrow 1306
			}
1307
			return false;
1308
		}
1309
	}
114 cycrow 1310
	if(peek(is)==bob_weights::HDR_BEGIN){
1 cycrow 1311
		if(!weights.load(is)){
1312
			for(ErrorIterator &it=weights.errors.begin(); it!=weights.errors.end(); ++it){
1313
				error(it->code, "weights->%s", it->text);
1314
			}
1315
			return false;
1316
		}
1317
	}
114 cycrow 1318
	if(peek(is)==bob_parts::HDR_BEGIN){
1 cycrow 1319
		if(parts.load(is)==false){
1320
			for(ErrorIterator &it=parts.errors.begin(); it!=parts.errors.end(); ++it){
1321
				error(it->code, "parts->%s", it->text);
1322
			}
1323
			return false;
1324
		}
1325
	}
1326
	return !is.fail();
1327
}
1328
//---------------------------------------------------------------------------------
114 cycrow 1329
bool bob_body::toFile(obinaryfilestream& os)
1 cycrow 1330
{
1331
	os << bodySize << bodyFlags;
114 cycrow 1332
 
1 cycrow 1333
	bones.toFile(os);
114 cycrow 1334
	vertices.toFile(os);
1 cycrow 1335
	weights.toFile(os);
114 cycrow 1336
	parts.toFile(os, vertices);
1337
 
1 cycrow 1338
	return os.good();
1339
}
1340
//---------------------------------------------------------------------------------
114 cycrow 1341
bool bob_body::toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, int idx)
1 cycrow 1342
{
1343
	os << "// beginning of body " << idx << endl;
1344
	os << autoSemicolons << bodySize << endl << endl;
114 cycrow 1345
 
1 cycrow 1346
	bones.toFile(os);
114 cycrow 1347
 
1348
	vertices.toFile(os, settings);
1349
 
1350
	weights.toFile(os, &vertices.map);
1351
 
1352
	if(parts.toFile(os, settings, materials, &vertices.map)==false){
1353
		for(bob_parts::ErrorIterator &e_it=parts.errors.begin(); e_it!=parts.errors.end(); ++e_it){
1354
			error(e_it->severity, e_it->code, "Parts->%s", e_it->text);
1355
		}
1356
		return false;
1357
	}
1 cycrow 1358
	char str[17]; int bit=1;
1359
	for(int i=15; i >= 0; i--){
1360
		str[i]=bodyFlags & bit ? '1' : '0';
1361
		bit<<=1;
1362
	}
1363
	str[sizeof(str)-1]=0;
114 cycrow 1364
 
1 cycrow 1365
	os << "-99" << str << noSemicolons << "// body " << idx << " end" << endl;
114 cycrow 1366
 
1 cycrow 1367
	return os.good();
1368
}
1369
//---------------------------------------------------------------------------------
1370
// BONES
114 cycrow 1371
bool bob_bones::load(ibinaryfilestream& is)
1 cycrow 1372
{
1373
	int hdr, count;
1374
	is >> hdr;
114 cycrow 1375
	if(hdr!=HDR_BEGIN){
1 cycrow 1376
		error(e_badHeader);
1377
		return false;
1378
	}
114 cycrow 1379
 
1 cycrow 1380
	is >> count;
1381
	char *name;
1382
	for(int i=0; i < count; i++){
1383
		is >> name;
1384
		if(name==0){
1385
			error(e_notEnoughData);
1386
			delete[] name;
1387
			return false;
1388
		}
1389
		push_back(name);
1390
	}
1391
	is >> hdr;
114 cycrow 1392
	if(hdr!=HDR_END){
1 cycrow 1393
		error(e_badEndHeader);
1394
		return false;
1395
	}
1396
	return true;
1397
}
1398
//---------------------------------------------------------------------------------
114 cycrow 1399
bool bob_bones::toFile(obinaryfilestream& os)
1 cycrow 1400
{
1401
	if(size()==0) return true;
114 cycrow 1402
 
1403
	os << HDR_BEGIN << (int) size();
1 cycrow 1404
	for(iterator &it=begin(); it!=end(); ++it){
1405
		os << *it;
1406
	}
114 cycrow 1407
	os << HDR_END;
1 cycrow 1408
	return os.good();
1409
}
1410
//---------------------------------------------------------------------------------
114 cycrow 1411
bool bob_bones::toFile(otextfilestream& os)
1 cycrow 1412
{
1413
	if(size()==0) return true;
1414
	os << noSemicolons << "BONES: " << autoSemicolons << (int)size() << endl;
1415
	for(iterator &it=begin(); it!=end(); ++it){
1416
		os << *it << endl;
1417
	}
1418
	os << endl;
1419
	return os.good();
1420
}
1421
//---------------------------------------------------------------------------------
1422
// WEIGHTS - section
114 cycrow 1423
bool bob_weights::load(ibinaryfilestream& is)
1 cycrow 1424
{
1425
	int hdr;
1426
	is >> hdr;
114 cycrow 1427
	if(hdr!=HDR_BEGIN){
1 cycrow 1428
		error(e_badHeader);
1429
		return false;
1430
	}
114 cycrow 1431
 
1 cycrow 1432
	int count;
1433
	is >> count;
1434
	resize(count);
114 cycrow 1435
 
1436
	bob_weight *ch;
1 cycrow 1437
	for(int i=0; i < count; i++){
114 cycrow 1438
		ch=new bob_weight();
1 cycrow 1439
		if(!ch->load(is)){
1440
			error(ch->errorCode, "weight[%d]: %s", i, bob_traslate_error(ch->errorCode));
1441
			delete ch;
1442
			return false;
1443
		}
1444
		(*this)[i]=ch;
1445
	}
1446
	is >> hdr;
114 cycrow 1447
	if(hdr!=HDR_END){
1 cycrow 1448
		error(e_badEndHeader);
1449
		return false;
1450
	}
1451
	return true;
1452
}
1453
//---------------------------------------------------------------------------------
114 cycrow 1454
bool bob_weights::toFile(obinaryfilestream& os)
1 cycrow 1455
{
1456
	if(new_weights.size()==0 && size()==0) return true;
114 cycrow 1457
 
1458
	os << HDR_BEGIN;
1 cycrow 1459
	if(new_weights.size()){
1460
		os << (int)new_weights.size();
1461
		for(WeightList::iterator &it=new_weights.begin(); it!=new_weights.end(); ++it){
1462
			it->toFile(os);
1463
		}
1464
	}
1465
	else{
1466
		os << (int)size();
1467
		for(iterator &it=begin(); it!=end(); ++it){
1468
			it->toFile(os);
1469
		}
1470
	}
114 cycrow 1471
 
1472
	os << HDR_END;
1 cycrow 1473
	return os.good();
1474
}
1475
//---------------------------------------------------------------------------------
114 cycrow 1476
bool bob_weights::toFile(otextfilestream& os, const bob_point_map *pointMap)
1 cycrow 1477
{
1478
	if(size()==0) return true;
1479
	os << noSemicolons << "WEIGHTS " << autoSemicolons << (int) pointMap->uniquePointsSize() << endl;
1480
	int i=0;
1481
	for(bob_point_map::const_index_iterator &it=pointMap->indexBegin(); it!=pointMap->indexEnd(); ++it){
1482
		(*this)[*it]->toFile(os, i++);
1483
	}
1484
	os << autoSemicolons << "-1" << endl << endl;
1485
	return os.good();
1486
}
1487
//---------------------------------------------------------------------------------
1488
// WEIGHT - object
114 cycrow 1489
bool bob_weight::load(ibinaryfilestream& is)
1 cycrow 1490
{
1491
	short count;
1492
	value v;
114 cycrow 1493
 
1 cycrow 1494
	is >> count;
114 cycrow 1495
 
1 cycrow 1496
	for(int i=0; i < count; i++){
1497
		is >> v.boneIdx >> v.boneCoefficient;
1498
		values.push_back(v);
1499
	}
114 cycrow 1500
 
1 cycrow 1501
	return !is.fail();
1502
}
1503
//---------------------------------------------------------------------------------
114 cycrow 1504
bool bob_weight::toFile(obinaryfilestream& os)
1505
{
1 cycrow 1506
	os << (short) values.size();
114 cycrow 1507
 
1 cycrow 1508
	value v;
1509
	for(iterator &it=values.begin(); it!=values.end(); ++it){
1510
		v=*it;
1511
		os << v.boneIdx << v.boneCoefficient;
1512
	}
1513
	return os.good();
1514
}
1515
//---------------------------------------------------------------------------------
114 cycrow 1516
bool bob_weight::toFile(otextfilestream& os, int idx)
1 cycrow 1517
{
1518
	os << autoSemicolons;
1519
	for(iterator &it=values.begin(); it!=values.end(); ++it){
1520
		(*it).toFile(os);
1521
	}
1522
	os << noSemicolons << "-1; // " << idx << endl;
1523
	return os.good();
1524
}
114 cycrow 1525
//---------------------------------------------------------------------------------
1526
bool bob_part::outputRaw(otextfilestream& os, const bob_point_map& pointMap, int idx)
1527
{
1528
	int oldf=os.flags();
1529
	os << noSemicolons << "// Part " << idx << endl << "// " << (int)numFaces() << " faces" << endl;
1530
	for(iterator& facelist_it=begin(); facelist_it!=end(); ++facelist_it){
1531
		os << noSemicolons << "// Material " << facelist_it->materialIndex << endl << autoSemicolons;
1532
		for(bob_face_list::iterator& face_it=facelist_it->begin(); face_it!=facelist_it->end(); ++face_it){
1533
			for(int i=0; i < 3; i++)
1534
				os << face_it->values[i];
1535
			os << face_it->flags;
1536
 
1537
			os << endl;
1538
		}
1539
	}
1540
 
1541
	bool bRes = true;
1542
 
1543
	if(flags & FLAG_X3) {
1544
		bRes = outputX3VertexData(os, pointMap);
1545
 
1546
		os << noSemicolons << "Collision sphere: offset: " << autoSemicolons << collisionBox.sphereOffset.x << collisionBox.sphereOffset.y << collisionBox.sphereOffset.z << noSemicolons << "diameter: " << autoSemicolons << collisionBox.sphereDiameter << endl;
1547
		os << noSemicolons << "Collision box: offset: " << autoSemicolons << collisionBox.boxOffset.x << collisionBox.boxOffset.y << collisionBox.boxOffset.z << noSemicolons << "size: " << autoSemicolons << collisionBox.boxSize.x << collisionBox.boxSize.y << collisionBox.boxSize.z << endl;
1548
	}
1549
 
1550
	os.flags(oldf);
1551
	return os.good() && bRes;
1552
}
1 cycrow 1553
//---------------------------------------------------------------------------------