Rev 1 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*
defines bob_bob - class that can manipulate the BOB1 format and all the
underlying objects
*/
#ifndef BOB_BOB_INCLUDED
#define BOB_BOB_INCLUDED
#include "bob_dom_base.h"
#include "settings.h"
#include "../common/ext_utils.h"
#include "../common/ext_array.h"
#include "../common/ext_simple_list.h"
#include "../common/strutils.h"
#include "../common/ptr_list.h"
#include "conversion.h"
class bob_dom_bob;
class bob_bodies;
class bob_body;
class bob_materials;
class bob_material3;
class bob_material5;
class bob_points;
class bob_vertex;
class bob_part;
class bob_face;
class bob_point_map;
enum X2BobType
{
bobX2,
bobX3
};
class bob_weight
{
public:
struct value
{
static const int MULTIPLIER = 65536;
short boneIdx;
int boneCoefficient;
void toFile(otextfilestream& os)
{
os << boneIdx << (boneCoefficient / (double)MULTIPLIER);
}
};
private:
public:
typedef ext::list<value>::iterator iterator;
typedef ext::list<value>::const_iterator const_iterator;
bob_error_codes errorCode;
ext::list<value> values;
bob_weight() { errorCode=e_noError; }
bob_weight(const bob_weight& other)
{
errorCode=other.errorCode;
for(const_iterator &it=other.values.begin(); it!=other.values.end(); ++it){
values.push_back(*it);
}
}
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, int idx);
};
class bob_weights : public bob_section, public ptr_list<ext::array<bob_weight*> >
{
public:
static const int HDR_BEGIN = BOB_SECTION_NAME_WEIGHT_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_WEIGHT_END;
typedef ptr_list<ext::simple_list<bob_weight*> > WeightList;
WeightList new_weights;
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, const bob_point_map *pointMap);
};
class bob_bones : public bob_section, public ptr_list<ext::list<char*> >
{
public:
static const int HDR_BEGIN = BOB_SECTION_NAME_BONE_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_BONE_END;
bool load(ibinaryfilestream &is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
};
class bob_material
{
public:
enum materialType
{
mat1,
mat3,
mat5,
mat6
};
materialType type;
short index;
bob_error_codes errorCode;
bob_material() { index=0; }
virtual ~bob_material() { }
virtual bool load(ibinaryfilestream& is) = 0;
virtual bool toFile(obinaryfilestream& os) = 0;
virtual bool toFile(otextfilestream& os) = 0;
};
class bob_material1 : public bob_material
{
public:
struct rgb
{
short r, g, b;
rgb() { r=g=b=0; }
};
struct pair
{
short value;
short strength;
pair() { value=0; strength=0; }
};
short textureID;
rgb ambient;
rgb diffuse;
rgb specular;
bob_material1()
{
type=mat1;
index=0; textureID=0; errorCode=e_noError;
}
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
};
inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, bob_material1::pair& right)
{
is >> right.value >> right.strength;
return is;
}
inline
obinaryfilestream& operator << (obinaryfilestream& os, bob_material1::pair& right)
{
os << right.value << right.strength;
return os;
}
inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, bob_material1::rgb& r)
{
is >> r.r >> r.g >> r.b;
return is;
}
inline
obinaryfilestream& operator << (obinaryfilestream& os, bob_material1::rgb& right)
{
os << right.r << right.g << right.b;
return os;
}
inline
otextfilestream& operator << (otextfilestream& os, bob_material1::pair& right)
{
int f=os.flags();
os << noSemicolons;
os << right.value << ';' << right.strength << "; ";
os.flags(f);
return os;
}
inline
otextfilestream& operator << (otextfilestream& os, bob_material1::rgb& right)
{
int f=os.flags();
os << noSemicolons;
os << right.r << ';' << right.g << ';' << right.b << "; ";
os.flags(f);
return os;
}
class bob_material3 : public bob_material1
{
public:
int transparency;
short selfIllumination;
pair shininess;
bool destinationBlend;
bool twoSided;
bool wireframe;
short textureValue;
pair enviromentMap;
pair bumpMap;
typedef bob_material1 base;
bob_material3() {
type=mat3;
transparency=0; selfIllumination=0; destinationBlend=0;
twoSided=0; wireframe=0; textureValue=0;
}
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
};
class bob_material5 : public bob_material3
{
private:
public:
typedef bob_material3 base;
pair lightMap;
bob_material5() { type=mat5; }
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
};
class material6_value
{
private:
static char *m_stringTypes[];
static int m_stringTypesCount;
public:
enum Type
{
typeLong=0,
typeBool=1,
typeFloat=2,
typeFloat4=5,
typeString=8
};
struct float4
{
float f[4];
};
union TagValue
{
bool b;
int i;
char *psz;
float f;
float4 f4;
} val;
Type type;
char *name;
material6_value() { val.i=0; type=typeLong; name=0; }
material6_value(Type type) { val.i=0; this->type=type; name=0; }
~material6_value() { delete name; if(type==typeString) delete val.psz; }
static const char * typeName(int type) { return type < m_stringTypesCount ? m_stringTypes[type] : ""; }
const char * typeName() const { return typeName(type); }
static int typeNameCount() { return m_stringTypesCount; }
bob_error_codes load(ibinaryfilestream& is);
bool toFile(otextfilestream& os);
bool toFile(obinaryfilestream& os);
};
inline ibinaryfilestream& operator >> (ibinaryfilestream& is, material6_value::float4 &val)
{
for(int i=0; i < 4; i++){
is >> val.f[i];
}
return is;
}
inline obinaryfilestream& operator << (obinaryfilestream& os, material6_value::float4 &val)
{
for(int i=0; i < 4; i++){
os << val.f[i];
}
return os;
}
class bob_material6_values : public ptr_list<ext::simple_list<material6_value*> >
{
public:
typedef ext::simple_list<material6_value*> base;
typedef base::iterator iterator;
public:
bob_error_codes load(ibinaryfilestream& is);
bool toFile(otextfilestream& os);
bool toFile(obinaryfilestream& os);
};
class bob_material6 : public bob_material
{
public:
class Big
{
public:
static const int flag=0x2000000;
char *effect;
short technique;
bob_material6_values values;
Big() { effect=0; technique=0; }
~Big() { delete[] effect; }
bob_error_codes load(ibinaryfilestream& is);
bool toFile(otextfilestream& os);
bool toFile(obinaryfilestream& os);
};
class Small
{
public:
struct pair
{
char *texture;
short strength;
pair() { texture=0; }
~pair() { delete[] texture; }
pair& operator = (const pair& other)
{
strcreate(texture, other.texture); strength=other.strength; return *this;
}
};
char *textureFile;
bob_material1::rgb ambient, diffuse, specular;
int transparency;
short selfIllumination;
bob_material1::pair shininess;
bool destinationBlend;
bool twoSided;
bool wireframe;
short textureValue;
pair enviromentMap;
pair bumpMap;
pair lightMap;
pair map4, map5;
Small() {
textureFile=0; transparency=0; selfIllumination=0; destinationBlend=false; twoSided=false; wireframe=false;
textureValue=0;
}
~Small()
{
delete[] textureFile;
}
bob_error_codes load(ibinaryfilestream& is, int flags);
bool toFile(otextfilestream& os);
bool toFile(obinaryfilestream& os);
};
public:
#ifdef small // some fucking definition from RPC (god knows where it's included)
#undef small
#endif
int flags;
Small *small;
Big *big;
bob_material6() { type=mat6; flags=0; small=0; big=0; }
~bob_material6() { delete small; delete big; }
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
};
inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, bob_material6::Small::pair& right)
{
is >> right.texture >> right.strength;
return is;
}
inline
obinaryfilestream& operator << (obinaryfilestream& os, bob_material6::Small::pair& right)
{
static char *empty="";
os << (right.texture ? right.texture : empty) << right.strength;
return os;
}
inline
otextfilestream& operator << (otextfilestream& os, bob_material6::Small::pair& right)
{
int old=os.flags();
os << noSemicolons << (*(right.texture)==0 ? "NULL" : right.texture) << ';' << autoSemicolons << right.strength;
os.flags(old);
return os;
}
class bob_materials : public bob_section, public ptr_list<ext::list<bob_material*> >
{
private:
public:
static const int HDR_MAT6_BEGIN = BOB_SECTION_NAME_MAT6_BEGIN;
static const int HDR_MAT5_BEGIN = BOB_SECTION_NAME_MAT5_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_MAT_END;
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
bool load(ibinaryfilestream& is);
};
#include "geometry_bob.h"
class bob_vertex : public vertex
{
public:
typedef point2d<double> uv_coord;
static const int FLAG_DEFAULT = 0x19;
static const int FLAG_UV = 2;
static const int FLAG_WEIRD_STUFF = 4;
private:
public:
short flags;
bob_error_codes errorCode;
uv_coord textureCoords;
point2d<double> weirdCoords;
int sgbits;
normal_vector normalVector;
normal_vector tangentVector;
public:
bob_vertex() { errorCode=e_noError; flags=0; }
bob_vertex(int x, int y, int z)
: vertex(x,y,z)
{
errorCode=e_noError;
flags=0;
}
bool hasTextureCoords() const { return (flags & FLAG_UV) > 0; }
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, int idx);
void getBodCoords(int *coords)
{
coords[0]=conversion::vertex_bob2bod(x);
coords[1]=conversion::vertex_bob2bod(y);
coords[2]=conversion::vertex_bob2bod(z);
}
};
// must be included AFTER the bob_vertex is defined
#include "../x2bc_common/bob_point_map.h"
class bob_vertices : public bob_section
{
public:
static const int HDR_BEGIN = BOB_SECTION_NAME_POINT_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_POINT_END;
typedef ptr_list<ext::array<bob_vertex*> > VertexArray;
typedef VertexArray::iterator VertexIterator;
public:
bob_point_map map;
VertexArray new_vertices;
private:
bool outputRaw(otextfilestream& os);
bool outputBOD(otextfilestream& os);
public:
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, const Settings& settings);
};
class bob_x3vertex_data_record
{
public:
int pointIndex; // index of BOB point
vector tangent;
vector unk;
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
};
class bob_x3vertex_data : public ptr_list<ext::array<bob_x3vertex_data_record*> >
{
public:
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
iterator search(int pointIndex)
{
int min=0, mid, res, max=(int)size() - 1;
if(max==-1) return end();
do {
mid=(max + min) / 2;
res=pointIndex - at(mid)->pointIndex;
if(res <= 0) max=mid - 1;
if(res >= 0) min=mid + 1;
}
while(min <= (int)max);
return pointIndex==at(mid)->pointIndex ? (m_first + mid) : end();
}
const_iterator search(int pointIndex) const
{
int min=0, mid, res, max=(int)size() - 1;
if(max==-1) return end();
do {
mid=(max + min) / 2;
res=pointIndex - at(mid)->pointIndex;
if(res <= 0) max=mid - 1;
if(res >= 0) min=mid + 1;
}
while(min <= (int)max);
return pointIndex==at(mid)->pointIndex ? (m_first + mid) : end();
}
};
class bob_face
{
public:
int values[3];
int flags;
bob_error_codes errorCode;
bob_face() { errorCode=e_noError; }
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
};
class bob_face_list : public ptr_list<ext::list<bob_face*> >, public bob_with_errors
{
private:
bool saveVertexTangents(obinaryfilestream& os, const bob_vertices& vertices);
public:
int materialIndex;
bob_x3vertex_data x3vertexData;
bob_face_list() { materialIndex=0; }
bool load(ibinaryfilestream& is, bool x3data);
bool toFile(obinaryfilestream& os, const bob_vertices& vertices, bool x3data);
bool outputX3VertexDataRaw(otextfilestream& os);
//bool computeAndOutputTangents(otextfilestream& os, const bob_point_map& pointMap);
};
class bob_part_collision_box
{
public:
point3d<double> sphereOffset;
double sphereDiameter;
point3d<double> boxOffset;
point3d<double> boxSize;
public:
bob_part_collision_box()
{
sphereDiameter = 0;
}
bool load(ibinaryfilestream& is);
bool toFile(otextfilestream& os);
bool toFile(obinaryfilestream& os);
};
class bob_part : public bob_with_errors, public ptr_list<ext::list<bob_face_list*> >
{
public:
static const int FLAG_X3 = 0x10000000;
static const int BOD_FLAG_UV = 8;
static const int BOD_FLAG_SGBITS = 16;
int flags;
bob_part_collision_box collisionBox;
private:
bool outputX3VertexData(otextfilestream& os, const bob_point_map& pointMap);
void outputExtraPtInfo(otextfilestream& os, const bob_vertex *points[]);
void outputNormals(otextfilestream& os, const bob_vertex *points[]);
bool outputRaw(otextfilestream& os, const bob_point_map& pointMap, int idx);
bool outputBOD(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map& pointMap, int idx);
public:
bob_part() { flags=0; }
size_t numFaces() const
{
size_t count=0;
for(const_iterator &it=begin(); it!=end(); ++it){
count+=it->size();
}
return count;
}
// find the appropriate face list based on material index
bob_face_list * operator[] (int matIdx)
{
for(reverse_iterator &it=rbegin(); it!=rend(); ++it){
if(it->materialIndex==matIdx)
return *it;
}
return NULL;
}
// find or create an appropriate face list based on material index
bob_face_list * facelist(int matIdx)
{
bob_face_list *p=(*this)[matIdx];
if(p==NULL){
p=new bob_face_list();
push_back(p);
p->materialIndex=matIdx;
}
return p;
}
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os, const bob_vertices& vertices);
bool toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map& pointMap, int idx);
};
class bob_parts : public bob_section, public ext::list<bob_part*>
{
public:
static const int HDR_BEGIN = BOB_SECTION_NAME_PART_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_PART_END;
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os, const bob_vertices& vertices);
bool toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, const bob_point_map *pointMap);
~bob_parts()
{
for(iterator &it=begin(); it!=end(); ++it){
delete *it;
}
}
};
class bob_body : public bob_with_errors
{
public:
bob_bones bones;
bob_vertices vertices;
bob_parts parts;
bob_weights weights;
int bodySize;
int bodyFlags;
bob_body() { bodySize=0; bodyFlags=0; }
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials, int idx);
};
class bob_bodies : public bob_section, public bob_cantainer<bob_body>
{
public:
static const int HDR_BEGIN = BOB_SECTION_NAME_BODY_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_BODY_END;
bool load(ibinaryfilestream& is);
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os, const Settings& settings, const bob_materials *materials);
};
class bob_dom_bob : public bob_section
{
private:
const Settings *m_settings;
public:
typedef bob_bodies::iterator BodyIterator;
bob_info info;
bob_materials materials;
bob_bodies bodies;
static const int HDR_BEGIN = BOB_SECTION_NAME_BOB_BEGIN;
static const int HDR_END = BOB_SECTION_NAME_BOB_END;
bob_dom_bob(const Settings *settings) { m_settings=settings; }
bool toFile(obinaryfilestream& os);
bool toFile(otextfilestream& os);
bool load(ibinaryfilestream& is);
};
#endif // !defined(BOB_BOB_INCLUDED)