Subversion Repositories spk

Rev

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

/*
  defines the bod_bob_parser - class that can parse bod format and create
  bob_dom_bob object
*/

#ifndef BOD_BOB_PARSER_INCLUDED
#define BOD_BOB_PARSER_INCLUDED

#include "bob_dom_bob.h"
#include "bod_text_parser.h"
#include "token_stream.h"
#include "settings.h"
#include "bod_parser_base.h"

#include "../common/ptr_list.h"
#include "geometry.h"

class bod_bob_parser : public bod_parser_base
{
        private:
                struct SameVertices;
                struct SameSG_UVs;
                
                struct uv_coord : geometry::point2d<double>
                {
                        friend SameSG_UVs;
                        private:
                                static geometry::point2d<double> NULL_COORDS;
                                
                                bool isNull () const { return *this==NULL_COORDS; }
                                
                        public:
                                SameSG_UVs *parent;
                                int vertexIndex;
                                
                                uv_coord(SameSG_UVs *p, double x, double y)
                                        : geometry::point2d<double>(x,y), parent(p) { }
                                        
                                bob_vertex * createBOBVertex()
                                {
                                        bob_vertex *v=new bob_vertex(parent->parent->x, parent->parent->y, parent->parent->z);
                                        v->sgbits=parent->sgbits;
                                        if(!isNull()){
                                                v->textureCoords.x=x;
                                                v->textureCoords.y=y;
                                                v->flags|=bob_vertex::FLAG_UV;
                                        }
                                        return v;
                                }
                };

                struct SameSG_UVs : public ptr_list<ext::simple_list<uv_coord*> >
                {
                        public:
                                SameVertices *parent;
                                int sgbits;
                                
                                SameSG_UVs (SameVertices *p, int sg)
                                        : sgbits(sg) { parent=p; }
                                
                                uv_coord * findUV(double x, double y)
                                {
                                        for(iterator &it=begin(); it!=end(); ++it){
                                                if(it->x==x && it->y==y)
                                                        return *it;
                                        }
                                        return 0;
                                }
                                uv_coord * createUV(double x, double y)
                                {
                                        uv_coord *uv=new uv_coord(this, x,y);
                                        push_back(uv);
                                        return uv;
                                }
                                
                                uv_coord * findNullUV()
                                {
                                        return findUV(uv_coord::NULL_COORDS.x, uv_coord::NULL_COORDS.y);
                                }
                                
                                uv_coord * createNullUV()
                                {
                                        return createUV(uv_coord::NULL_COORDS.x, uv_coord::NULL_COORDS.y);
                                }
                };

                struct SameVertices : public vertex, public ptr_list<ext::simple_list<SameSG_UVs*> >
                {
                        SameVertices(int x, int y, int z)
                        {
                                this->x=conversion::vertex_bod2bob(x);
                                this->y=conversion::vertex_bod2bob(y);
                                this->z=conversion::vertex_bod2bob(z);
                        }
                        
                        SameSG_UVs * findTextureCoords(int sgbits)
                        {
                                for(iterator &it=begin(); it!=end(); ++it){
                                        //if(it->sgbits==sgbits) return *it;
                                        /* changed and not tested - taken from max2msh by mindblast */
                                        if(it->sgbits & sgbits) return *it;
                                }
                                SameSG_UVs *uvs=new SameSG_UVs(this, sgbits);
                                push_back(uvs);
                                return uvs;
                        }

                };

        protected:
                const Settings *m_settings;

                bool checkImmediatePlacement(const bod_bob_parser::token *token1, const bod_bob_parser::token *token2);

        private:
                typedef ext::simple_list<SameVertices*> VertexList;
                typedef ptr_list<ext::array<SameVertices*> > VertexArray;
                typedef ptr_list<ext::array<bob_weight*> > WeightArray;

                const bob_materials *m_materials;
                VertexArray m_vertices;
                WeightArray m_weights;

        private:
                bool loadMatRGB(token_stream& is, bob_material5::rgb& rgb);
                bool loadMatPair(token_stream& is, bob_material5::pair& pair);
                bool loadMatPair(token_stream& is, bob_material6::Small::pair& pair);
                bool loadMat(bob_material5 *mat, token_stream &is);
                bool loadMat(bob_material6 *mat, token_stream &is);
                bool loadMaterial(bob_dom_bob *bob, token_stream& is);
                bool loadBody(bob_dom_bob *bob, token_stream& is);
                bool loadVertices(bob_body *body, token_stream& is, VertexList& points);
                bool loadPart(bob_body *body, token_stream& is);
                bool loadFace(int matIdx, bob_body& body, bob_part& part, token_stream& is);
                bool flagsFromString(token_stream& is, int& flags);
                
                void computeVertexTangents(bob_body& body);
                
                material6_value * loadMat6Value(token_stream& is);

                bool loadMaterial6Small(bob_material6 *mat, token_stream &is);
                bool loadMaterial6Big(bob_material6 *mat, token_stream &is);

                bool loadSpecialValues(bob_vertex *points[3], token_stream& is);
                bool loadSpecialPointValues(token_stream& is, bob_vertex *point);
                bool loadFaceNormal(token_stream& is, bob_vertex *points[3]);

                bool loadBones(bob_body *body, token_stream& is);
                bool loadWeights(bob_body *body, token_stream& is);

                bool loadCollisionBoxData(token_stream& is, bob_part& part);

                void deleteTempData()
                {
                        m_vertices.clear();
                        m_weights.clear();
                }

        public:

                bod_bob_parser(const Settings *settings) { m_settings=settings; }
                ~bod_bob_parser() { deleteTempData(); }

                bob_dom_bob * loadBOB(token_stream& is, bool bEmbedded);

                bool compile(token_stream& is, obinaryfilestream& os, bool bEmbedded);
};

#endif //!defined(BOD_BOB_PARSER_INCLUDED)