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