Subversion Repositories spk

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
/*
2
  defines bob_dom_bob - class that can manipulate the BOB1 format and all the 
3
  underlying objects
4
*/
5
 
6
#ifndef BOB_DOM_BOB_INCLUDED
7
#define BOB_DOM_BOB_INCLUDED
8
 
9
#include "bob_dom_base.h"
10
#include "settings.h"
11
#include "../common/ext_utils.h"
12
#include "../common/ext_array.h"
13
#include "../common/ext_simple_list.h"
14
#include "../common/strutils.h"
15
 
16
class bob_dom_bob;
17
 
18
class bob_dom_bodies;
19
class bob_dom_body;
20
 
21
class bob_dom_materials;
22
class bob_dom_material3;
23
class bob_dom_material5;
24
 
25
class bob_dom_points;
26
class bob_dom_point;
27
 
28
class bob_dom_part;
29
class bob_dom_face;
30
 
31
class bob_point_map;
32
 
33
enum X2BobType
34
{
35
	bobX2,
36
	bobX3
37
};
38
 
39
 
40
class bob_dom_weight
41
{
42
	public:
43
		struct value
44
		{
45
			static const int multiplier = 65536;
46
 
47
			short boneIdx;
48
			int boneCoefficient;
49
 
50
			void toFile(bob_dom_otextfilestream& os)
51
			{
52
				os << boneIdx << (float)(boneCoefficient / (double)multiplier);
53
			}
54
 
55
		};
56
 
57
	private:
58
 
59
	public:
60
		typedef ext::list<value>::iterator iterator;
61
		typedef ext::list<value>::const_iterator const_iterator;
62
 
63
		bob_error_codes errorCode;
64
		ext::list<value> values;
65
 
66
		bob_dom_weight() { errorCode=e_noError; }
67
		bob_dom_weight(const bob_dom_weight& other) 
68
		{ 
69
			errorCode=other.errorCode; 
70
			for(const_iterator &it=other.values.begin(); it!=other.values.end(); ++it){
71
				values.push_back(*it);
72
			}
73
		}
74
 
75
		bool load(bob_dom_ibinaryfilestream& is);
76
 
77
		bool toFile(bob_dom_obinaryfilestream& os);
78
		bool toFile(bob_dom_otextfilestream& os, int idx);
79
};
80
 
81
class bob_dom_weights : public bob_dom_section, public ext::array<bob_dom_weight*>
82
{
83
	public:
84
		static const int hdr_begin=BOB_SECTION_NAME_WEIGHT_BEGIN;
85
		static const int hdr_end=BOB_SECTION_NAME_WEIGHT_END;
86
 
87
		typedef ext::simple_list<bob_dom_weight*> WeightList;
88
 
89
		WeightList new_weights;
90
 
91
		bool load(bob_dom_ibinaryfilestream& is);
92
 
93
		bool toFile(bob_dom_obinaryfilestream& os);
94
		bool toFile(bob_dom_otextfilestream& os, const bob_point_map *pointMap);
95
 
96
		~bob_dom_weights()
97
		{
98
			for(iterator &it=begin(); it!=end(); ++it){
99
				delete *it;
100
			}
101
			for(WeightList::iterator &it=new_weights.begin(); it!=new_weights.end(); ++it){
102
				delete *it;
103
			}
104
		}
105
};
106
 
107
class bob_dom_bones : public bob_dom_section, public ext::list<char*>
108
{
109
	public:
110
		static const int hdr_begin=BOB_SECTION_NAME_BONE_BEGIN;
111
		static const int hdr_end=BOB_SECTION_NAME_BONE_END;
112
 
113
		bool load(bob_dom_ibinaryfilestream &is);
114
 
115
		bool toFile(bob_dom_obinaryfilestream& os);
116
		bool toFile(bob_dom_otextfilestream& os);
117
 
118
		~bob_dom_bones()
119
		{
120
			for(iterator &it=begin(); it!=end(); ++it){
121
				delete *it;
122
			}
123
		}
124
};
125
 
126
class bob_dom_material
127
{
128
	public:
129
		enum materialType
130
		{
131
			mat1,
132
			mat3,
133
			mat5,
134
			mat6
135
		};
136
 
137
		materialType type;
138
		short index;
139
 
140
		bob_error_codes errorCode;
141
 
142
		bob_dom_material() { index=0; }
143
		virtual ~bob_dom_material() { }
144
 
145
		virtual bool load(bob_dom_ibinaryfilestream& is) = 0;
146
 
147
		virtual bool toFile(bob_dom_obinaryfilestream& os) = 0;
148
		virtual bool toFile(bob_dom_otextfilestream& os) = 0;
149
};
150
 
151
class bob_dom_material1 : public bob_dom_material
152
{
153
	public:
154
		struct rgb
155
		{
156
			short r, g, b;
157
			rgb() { r=g=b=0; }
158
		};
159
 
160
		struct pair
161
		{
162
			short value;
163
			short strength;
164
			pair() { value=0; strength=0; }
165
		};
166
 
167
		short textureID;
168
		rgb ambient;
169
		rgb diffuse;
170
		rgb specular;
171
 
172
		bob_dom_material1()
173
		{
174
			type=mat1;
175
			index=0; textureID=0; errorCode=e_noError;
176
		}
177
 
178
		bool load(bob_dom_ibinaryfilestream& is);
179
 
180
		bool toFile(bob_dom_obinaryfilestream& os);
181
		bool toFile(bob_dom_otextfilestream& os);
182
};
183
 
184
inline
185
bob_dom_ibinaryfilestream& operator >> (bob_dom_ibinaryfilestream& is, bob_dom_material1::pair& right)
186
{
187
	is >> right.value >> right.strength;
188
	return is;
189
}
190
 
191
inline
192
bob_dom_obinaryfilestream& operator << (bob_dom_obinaryfilestream& os, bob_dom_material1::pair& right)
193
{
194
	os << right.value << right.strength;
195
	return os;
196
}
197
 
198
inline
199
bob_dom_ibinaryfilestream& operator >> (bob_dom_ibinaryfilestream& is, bob_dom_material1::rgb& r)
200
{
201
	is >> r.r >> r.g >> r.b;
202
	return is;
203
}
204
 
205
inline
206
bob_dom_obinaryfilestream& operator << (bob_dom_obinaryfilestream& os, bob_dom_material1::rgb& right)
207
{
208
	os << right.r << right.g << right.b;
209
	return os;
210
}
211
 
212
inline
213
bob_dom_otextfilestream& operator << (bob_dom_otextfilestream& os, bob_dom_material1::pair& right)
214
{
215
	int f=os.flags();
216
	os << noSemicolons;
217
	os << right.value << ';' << right.strength << "; ";
218
	os.flags(f);
219
	return os;
220
}
221
 
222
inline
223
bob_dom_otextfilestream& operator << (bob_dom_otextfilestream& os, bob_dom_material1::rgb& right)
224
{
225
	int f=os.flags();
226
	os << noSemicolons;
227
	os << right.r << ';' << right.g << ';' << right.b << "; ";
228
	os.flags(f);
229
	return os;
230
}
231
 
232
class bob_dom_material3 : public bob_dom_material1
233
{
234
	public:
235
		int transparency;
236
		short selfIllumination;
237
		pair shininess;
238
		bool destinationBlend;
239
		bool twoSided;
240
		bool wireframe;
241
		short textureValue;
242
		pair enviromentMap;
243
		pair bumpMap;
244
 
245
		typedef bob_dom_material1 base;
246
 
247
		bob_dom_material3() {
248
			type=mat3;
249
			transparency=0; selfIllumination=0; destinationBlend=0;
250
			twoSided=0; wireframe=0; textureValue=0; 
251
		}
252
 
253
		bool load(bob_dom_ibinaryfilestream& is);
254
 
255
		bool toFile(bob_dom_obinaryfilestream& os);
256
		bool toFile(bob_dom_otextfilestream& os);
257
};
258
 
259
class bob_dom_material5 : public bob_dom_material3
260
{
261
	private:
262
 
263
	public:
264
		typedef bob_dom_material3 base;
265
 
266
		pair lightMap;
267
 
268
		bob_dom_material5() { type=mat5; }
269
 
270
		bool load(bob_dom_ibinaryfilestream& is);
271
 
272
		bool toFile(bob_dom_obinaryfilestream& os);
273
		bool toFile(bob_dom_otextfilestream& os);
274
 
275
};
276
 
277
class material6_value
278
{
279
	private:
280
		static char *m_stringTypes[];
281
		static int m_stringTypesCount;
282
 
283
	public:
284
		enum Type 
285
		{
286
			typeLong=0,
287
			typeBool=1,
288
			typeFloat=2,
289
			typeFloat4=5,
290
			typeString=8
291
		};
292
 
293
		struct float4
294
		{
295
			float f[4];
296
		};
297
 
298
		union TagValue
299
		{
300
			bool b;
301
			int i;
302
			char *psz;
303
			float f;
304
			float4 f4;
305
		} val;
306
 
307
		Type type;
308
		char *name;
309
 
310
		material6_value() { val.i=0; type=typeLong; name=0; }
311
		material6_value(Type type) { val.i=0; this->type=type; name=0; }
312
 
313
		~material6_value() { delete name; if(type==typeString) delete val.psz; }
314
 
315
		static const char * typeName(int type) { return type < m_stringTypesCount ? m_stringTypes[type] : ""; }
316
		const char * typeName() const { return typeName(type); }
317
		static int typeNameCount() { return m_stringTypesCount; }
318
 
319
		bob_error_codes load(bob_dom_ibinaryfilestream& is);
320
		bool toFile(bob_dom_otextfilestream& os);
321
		bool toFile(bob_dom_obinaryfilestream& os);
322
};
323
 
324
inline bob_dom_ibinaryfilestream& operator >> (bob_dom_ibinaryfilestream& is, material6_value::float4 &val)
325
{
326
	for(int i=0; i < 4; i++){
327
		is >> val.f[i];
328
	}
329
	return is;
330
}
331
 
332
inline bob_dom_obinaryfilestream& operator << (bob_dom_obinaryfilestream& os, material6_value::float4 &val)
333
{
334
	for(int i=0; i < 4; i++){
335
		os << val.f[i];
336
	}
337
	return os;
338
}
339
 
340
class bob_dom_material6_values : public ext::simple_list<material6_value*>
341
{
342
	public:
343
		typedef ext::simple_list<material6_value*> base;
344
		typedef base::iterator iterator;
345
 
346
	public:
347
		~bob_dom_material6_values()
348
		{
349
			for(iterator it=begin(); it!=end(); ++it){
350
				delete *it;
351
			}
352
		}
353
 
354
		bob_error_codes load(bob_dom_ibinaryfilestream& is);
355
 
356
		bool toFile(bob_dom_otextfilestream& os);
357
		bool toFile(bob_dom_obinaryfilestream& os);
358
};
359
 
360
class bob_dom_material6 : public bob_dom_material
361
{
362
	public:
363
		class Big
364
		{
365
			public:
366
				static const int flag=0x2000000;
367
 
368
				char *effect;
369
				short technique;
370
 
371
				bob_dom_material6_values values;
372
 
373
				Big() { effect=0; technique=0; }
374
				~Big() { delete[] effect; }
375
 
376
				bob_error_codes load(bob_dom_ibinaryfilestream& is);
377
 
378
				bool toFile(bob_dom_otextfilestream& os);
379
				bool toFile(bob_dom_obinaryfilestream& os);
380
		};
381
 
382
		class Small
383
		{
384
			public:	
385
				struct pair
386
				{
387
					char *texture;
388
					short strength;
389
 
390
					pair() { texture=0; }
391
					~pair() { delete[] texture; }
392
 
393
					pair& operator = (const pair& other) 
394
					{ 
395
						strcreate(texture, other.texture); strength=other.strength; return *this; 
396
					}
397
				};
398
 
399
				char *textureFile;
400
				bob_dom_material1::rgb ambient, diffuse, specular;
401
				int transparency;
402
				short selfIllumination;
403
				bob_dom_material1::pair shininess;
404
				bool destinationBlend;
405
				bool twoSided;
406
				bool wireframe;
407
				short textureValue;
408
				pair enviromentMap;
409
				pair bumpMap;
410
				pair lightMap;
411
				pair map4, map5;
412
 
413
				Small() { 
414
					textureFile=0; transparency=0; selfIllumination=0; destinationBlend=false; twoSided=false; wireframe=false;
415
					textureValue=0;
416
				}
417
				~Small() 
418
				{ 
419
					delete[] textureFile; 
420
				}
421
 
422
				bob_error_codes load(bob_dom_ibinaryfilestream& is, int flags);
423
 
424
				bool toFile(bob_dom_otextfilestream& os);
425
				bool toFile(bob_dom_obinaryfilestream& os);
426
		};
427
 
428
	public:
429
#ifdef small // some fucking definition from RPC (god knows where it's included)
430
	#undef small
431
#endif
432
		int flags;
433
		Small *small;
434
		Big *big;
435
 
436
		bob_dom_material6() { type=mat6; flags=0; small=0; big=0; }
437
		~bob_dom_material6() { delete small; delete big; }
438
 
439
		bool load(bob_dom_ibinaryfilestream& is);
440
 
441
		bool toFile(bob_dom_obinaryfilestream& os);
442
		bool toFile(bob_dom_otextfilestream& os);
443
};
444
 
445
inline
446
bob_dom_ibinaryfilestream& operator >> (bob_dom_ibinaryfilestream& is, bob_dom_material6::Small::pair& right)
447
{
448
	is >> right.texture >> right.strength;
449
	return is;
450
}
451
 
452
inline
453
bob_dom_obinaryfilestream& operator << (bob_dom_obinaryfilestream& os, bob_dom_material6::Small::pair& right)
454
{
455
	static char *empty="";
456
	os << (right.texture ? right.texture : empty) << right.strength;
457
	return os;
458
}
459
 
460
inline
461
bob_dom_otextfilestream& operator << (bob_dom_otextfilestream& os, bob_dom_material6::Small::pair& right)
462
{
463
	int old=os.flags();
464
	os << noSemicolons << (*(right.texture)==0 ? "NULL" : right.texture) << ';' << autoSemicolons << right.strength;
465
	os.flags(old);
466
	return os;
467
}
468
 
469
class bob_dom_materials : public bob_dom_section, public ext::list<bob_dom_material*>
470
{
471
	private:
472
 
473
	public:
474
		static const int hdr_mat6_begin=BOB_SECTION_NAME_MAT6_BEGIN;
475
		static const int hdr_mat5_begin=BOB_SECTION_NAME_MAT5_BEGIN;
476
		static const int hdr_end=BOB_SECTION_NAME_MAT_END;
477
 
478
		bob_dom_materials() { }
479
		~bob_dom_materials() 
480
		{ 
481
			for(iterator &it=begin(); it!=end(); ++it) {
482
				delete *it;
483
			}
484
		}
485
 
486
		bool toFile(bob_dom_obinaryfilestream& os);
487
		bool toFile(bob_dom_otextfilestream& os);
488
 
489
		bool load(bob_dom_ibinaryfilestream& is);
490
};
491
 
492
class bob_dom_point
493
{
494
	public:
495
		static double multiplier;
496
		typedef ext::list<int>::iterator iterator;
497
		typedef ext::list<int>::const_iterator const_iterator;
498
		typedef ext::pair<int, int>  pair;
499
 
500
		short type;
501
		ext::list<int> values;
502
		bob_error_codes errorCode;
503
 
504
		int x;
505
		int y;
506
		int z;
507
		pair textureCoords;
508
 
509
		bob_dom_point() { errorCode=e_noError; }
510
 
511
		bool load(bob_dom_ibinaryfilestream& is);
512
 
513
		bool toFile(bob_dom_obinaryfilestream& os);
514
		bool toFile(bob_dom_otextfilestream& os, int idx);
515
 
516
		bool operator ==(const bob_dom_point& right) const
517
		{
518
			return x==right.x && y==right.y && z==right.z;
519
		}
520
};
521
 
522
// must be included AFTER the bob_dom_point is defined
523
#include "../x2bc_common/bob_point_map.h"
524
 
525
class bob_dom_points : public bob_dom_section
526
{
527
	public:
528
		static const int hdr_begin=BOB_SECTION_NAME_POINT_BEGIN;
529
		static const int hdr_end=BOB_SECTION_NAME_POINT_END;
530
 
531
		bob_point_map map;
532
 
533
		ext::simple_list<bob_dom_point*> new_points;
534
		typedef ext::simple_list<bob_dom_point*>::iterator PointIterator;
535
 
536
		bool load(bob_dom_ibinaryfilestream& is);
537
 
538
		bool toFile(bob_dom_obinaryfilestream& os);
539
		bool toFile(bob_dom_otextfilestream& os);
540
 
541
		~bob_dom_points()
542
		{
543
			for(PointIterator &it=new_points.begin(); it!=new_points.end(); ++it){
544
				delete *it;
545
			}
546
		}
547
};
548
 
549
class bob_x3uv
550
{
551
	public:
552
		int idx; // ??
553
		float values[6];
554
 
555
		bool load(bob_dom_ibinaryfilestream& is);
556
 
557
		bool toFile(bob_dom_otextfilestream& os, int matIdx);
558
		bool toFile(bob_dom_obinaryfilestream& os);
559
};
560
 
561
class bob_x3uv_list : public ext::array<bob_x3uv*>
562
{
563
	public:
564
		~bob_x3uv_list() 
565
		{
566
			for(iterator &it=begin(); it!=end(); ++it) {
567
				delete *it;
568
			}
569
		}
570
 
571
		bool load(bob_dom_ibinaryfilestream& is);
572
 
573
		bool toFile(bob_dom_otextfilestream& os, int matIdx);
574
		bool toFile(bob_dom_obinaryfilestream& os);
575
 
576
		iterator search(int faceIdx)
577
		{
578
			int min=0, mid, res, max=(int)size() - 1;
579
 
580
			if(max==-1) return end();
581
			do {
582
				mid=((int)max + min) / 2;
583
				res=faceIdx - at(mid)->idx;
584
				if(res <= 0) max=mid - 1;
585
				if(res >= 0) min=mid + 1;
586
			}
587
			while(min <= (int)max);
588
			return faceIdx==at(mid)->idx ? (m_first + mid) : end();
589
		}
590
};
591
 
592
class bob_dom_face
593
{
594
	public:
595
		int values[4];
596
		bob_error_codes errorCode;
597
 
598
		bob_dom_face() { errorCode=e_noError; }
599
		bool load(bob_dom_ibinaryfilestream& is);
600
 
601
		bool toFile(bob_dom_obinaryfilestream& os);
602
};
603
 
604
class bob_face_list : public ext::list<bob_dom_face*>, public bob_with_errors
605
{
606
	public:
607
		int materialIndex;
608
		bob_x3uv_list x3uvlist;
609
 
610
		bob_face_list() { materialIndex=0; }
611
		~bob_face_list() 
612
		{ 
613
			for(iterator &it=begin(); it!=end(); ++it) {
614
				delete *it;
615
			}
616
		}
617
 
618
		bool load(bob_dom_ibinaryfilestream& is, bool x3data);
619
		bool toFile(bob_dom_obinaryfilestream& os, bool x3data);
620
};
621
 
622
class bob_dom_part_x3vals
623
{
624
	private:
625
		int m_values[10];
626
 
627
	public:
628
		bob_dom_part_x3vals() { memset(m_values, 0, sizeof(m_values)); }
629
 
630
		bool load(bob_dom_ibinaryfilestream& is);
631
		bool toFile(bob_dom_otextfilestream& os, bool bCommentItself);
632
		bool toFile(bob_dom_obinaryfilestream& os);
633
 
634
		int& operator [] (int idx) { return m_values[idx]; }
635
};
636
 
637
class bob_dom_part : public bob_with_errors, public ext::list<bob_face_list*>
638
{
639
	public:
640
		static const double multiplier;
641
		static const int x3flag=0x10000000;
642
 
643
		int flags;
644
 
645
		bob_dom_part_x3vals values;
646
 
647
		bob_dom_part()	{ flags=0; }
648
 
649
		~bob_dom_part()
650
		{
651
			for(iterator &it=begin(); it!=end(); ++it){
652
				delete *it;
653
			}
654
		}
655
 
656
		// find the appropriate face list based on material index
657
		bob_face_list * operator[] (int matIdx)
658
		{
659
			for(reverse_iterator &it=rbegin(); it!=rend(); ++it){
660
				if(it->materialIndex==matIdx)
661
					return *it;
662
			}
663
			return NULL;
664
		}
665
 
666
		// find or create an appropriate face list based on material index
667
		bob_face_list * facelist(int matIdx)
668
		{
669
			bob_face_list *p=(*this)[matIdx];
670
			if(p==NULL){
671
				p=new bob_face_list();
672
				push_back(p);
673
				p->materialIndex=matIdx;
674
			}
675
			return p;
676
		}
677
 
678
		bool load(bob_dom_ibinaryfilestream& is);
679
 
680
		bool toFile(bob_dom_obinaryfilestream& os);
681
		bool toFile(bob_dom_otextfilestream& os, const Settings *settings, const bob_dom_materials *materials, const bob_point_map *pointMap, int idx);
682
 
683
};
684
 
685
class bob_dom_parts : public bob_dom_section, public ext::list<bob_dom_part*>
686
{
687
	public:
688
		static const int hdr_begin=BOB_SECTION_NAME_PART_BEGIN;
689
		static const int hdr_end=BOB_SECTION_NAME_PART_END;
690
 
691
		bool load(bob_dom_ibinaryfilestream& is);
692
 
693
		bool toFile(bob_dom_obinaryfilestream& os);
694
		bool toFile(bob_dom_otextfilestream& os, const Settings *settings, const bob_dom_materials *materials, const bob_point_map *pointMap);
695
 
696
		~bob_dom_parts()
697
		{
698
			for(iterator &it=begin(); it!=end(); ++it){
699
				delete *it;
700
			}
701
		}
702
};
703
 
704
class bob_dom_body : public bob_with_errors
705
{
706
	public:
707
		bob_dom_bones bones;
708
		bob_dom_points points;
709
		bob_dom_parts parts;
710
		bob_dom_weights weights;
711
 
712
		int bodySize;
713
		int bodyFlags;
714
 
715
		bob_dom_body() { bodySize=0; bodyFlags=0; }
716
 
717
		bool load(bob_dom_ibinaryfilestream& is);
718
 
719
		bool toFile(bob_dom_obinaryfilestream& os);
720
		bool toFile(bob_dom_otextfilestream& os, const Settings *settings, const bob_dom_materials *materials, int idx);
721
};
722
 
723
class bob_dom_bodies : public bob_dom_section, public bob_dom_cantainer<bob_dom_body>
724
{
725
	public:
726
		static const int hdr_begin=BOB_SECTION_NAME_BODY_BEGIN;
727
		static const int hdr_end=BOB_SECTION_NAME_BODY_END;
728
 
729
		bool load(bob_dom_ibinaryfilestream& is);
730
 
731
		bool toFile(bob_dom_obinaryfilestream& os);
732
		bool toFile(bob_dom_otextfilestream& os, const Settings *settings, const bob_dom_materials *materials);
733
};
734
 
735
class bob_dom_bob : public bob_dom_section
736
{
737
	private:
738
		const Settings *m_settings;
739
 
740
	public:
741
		typedef bob_dom_bodies::iterator BodyIterator;
742
 
743
		bob_dom_info info;
744
		bob_dom_materials materials;
745
		bob_dom_bodies bodies;
746
 
747
		static const int hdr_begin=BOB_SECTION_NAME_BOB_BEGIN;
748
		static const int hdr_end=BOB_SECTION_NAME_BOB_END;
749
 
750
		bob_dom_bob(const Settings *settings) { m_settings=settings; }
751
 
752
		bool toFile(bob_dom_obinaryfilestream& os);
753
		bool toFile(bob_dom_otextfilestream& os);
754
 
755
		bool load(bob_dom_ibinaryfilestream& is);
756
		bool load(unsigned char *data, size_t size);
757
};
758
 
759
inline
760
bob_dom_otextfilestream& operator <<(bob_dom_otextfilestream& os, bob_dom_bob& right)
761
{
762
	right.toFile(os);
763
	return os;
764
}
765
 
766
#endif // !defined(BOB_DOM_BOB_INCLUDED)