⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 object.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*******************************************************      Lightwave Object Loader for OSG  Copyright (C) 2004 Marco Jez <marco.jez@poste.it>  OpenSceneGraph is (C) 2004 Robert Osfield********************************************************/#include "Object.h"#include <osg/Notify>#include <vector>#include <string>#include <sstream>using namespace lwosg;namespace{    bool triangle_is_clockwise(const osg::Vec3Array *points, int a, int b, int c)    {        const osg::Vec3 &A = (*points)[a];        const osg::Vec3 &B = (*points)[b];        const osg::Vec3 &C = (*points)[c];        float area2 = 0;        area2 += A.x() * B.y() - B.x() * A.y();        area2 += B.x() * C.y() - C.x() * B.y();        area2 += C.x() * A.y() - A.x() * C.y();        return area2 < 0;    }    float cylindrical_angle(float x, float y)    {        float r = sqrtf(x*x+y*y);        if (r == 0) return 0;        x /= r;        float a;        if (x < 0 && y >= 0) a = osg::PI_2 - acosf(-x);        else if (x < 0 && y < 0) a = acosf(-x) + osg::PI_2;        else if (x >= 0 && y >= 0) a = acosf(x) + 3 * osg::PI_2;        else if (x >= 0 && y < 0) a = 3 * osg::PI_2 - acosf(x);                else a = 0.0f;        return a/osg::PI/2;    }}Object::Object():    csf_(new LwoCoordFixer){}Object::Object(const iff::Chunk_list &data):    csf_(new LwoCoordFixer){    build(data);}void Object::build(const iff::Chunk_list &data){    clips_.clear();    surfaces_.clear();    layers_.clear();    comment_ = "";    description_ = "";    osg::notify(osg::INFO) << "INFO: lwosg::Object: scanning clips\n";    scan_clips(data);    osg::notify(osg::INFO) << "INFO: lwosg::Object: scanning surfaces\n";    scan_surfaces(data);    osg::notify(osg::INFO) << "INFO: lwosg::Object: parsing LWO2 chunks and building object\n";    parse(data);    osg::notify(osg::INFO) << "INFO: lwosg::Object: generating normals\n";    generate_normals();    osg::notify(osg::INFO) << "INFO: lwosg::Object: generating automatic texture maps\n";    generate_auto_texture_maps();}void Object::scan_clips(const iff::Chunk_list &data){    for (iff::Chunk_list::const_iterator i=data.begin(); i!=data.end(); ++i) {        const lwo2::FORM::CLIP *clip = dynamic_cast<const lwo2::FORM::CLIP *>(*i);        if (clip) {            clips_[clip->index] = Clip(clip);        }    }}void Object::scan_surfaces(const iff::Chunk_list &data){    for (iff::Chunk_list::const_iterator i=data.begin(); i!=data.end(); ++i) {        const lwo2::FORM::SURF *surf = dynamic_cast<const lwo2::FORM::SURF *>(*i);        if (surf) {            surfaces_[surf->name] = Surface(surf, clips_);        }    }}void Object::parse(const iff::Chunk_list &data){    typedef std::vector<std::string> String_list;    String_list tag_strings;    Layer current_layer;    for (iff::Chunk_list::const_iterator i=data.begin(); i!=data.end(); ++i) {        const lwo2::FORM::LAYR *layr = dynamic_cast<const lwo2::FORM::LAYR *>(*i);        if (layr) {            if (!current_layer.units().empty() || current_layer.get_layer_chunk()) {                layers_[current_layer.number()] = current_layer;            }            current_layer.set_layer_chunk(layr);            current_layer.units().clear();        }        const lwo2::FORM::PNTS *pnts = dynamic_cast<const lwo2::FORM::PNTS *>(*i);        if (pnts) {            Unit new_unit;            for (lwo2::FORM::PNTS::Point_list::const_iterator i=pnts->point_location.begin(); i!=pnts->point_location.end(); ++i) {                new_unit.points()->push_back(csf_->fix_point(osg::Vec3(i->X, i->Y, i->Z) /*+ current_layer.pivot()*/));                            }            new_unit.shares().assign(new_unit.points()->size(), Unit::Index_list());            current_layer.units().push_back(new_unit);        }        const lwo2::FORM::VMAP *vmap = dynamic_cast<const lwo2::FORM::VMAP *>(*i);        if (vmap && !current_layer.units().empty()) {            std::string type(vmap->type.id, 4);            if (type == "WGHT") {                if (vmap->dimension != 1) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().weight_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), 0, 0, 0);                }            }            if (type == "MNVW") {                if (vmap->dimension != 1) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().subpatch_weight_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), 0, 0, 0);                }            }            if (type == "TXUV") {                if (vmap->dimension != 2) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().texture_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), 0, 0);                }            }            if (type == "RGB ") {                if (vmap->dimension != 3) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().rgb_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), i->value.at(2), 1);                }            }            if (type == "RGBA") {                if (vmap->dimension != 4) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().rgba_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), i->value.at(2), i->value.at(3));                }            }            if (type == "MORF") {                if (vmap->dimension != 3) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().displacement_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), i->value.at(2), 0);                }            }            if (type == "SPOT") {                if (vmap->dimension != 3) {                    osg::notify(osg::WARN) << "Warning: Lwo2Object: invalid " << type << " vertex map dimension: " << vmap->dimension << std::endl;                    continue;                }                VertexMap *new_map = current_layer.units().back().spot_maps()->getOrCreate(vmap->name);                for (lwo2::FORM::VMAP::Mapping_list::const_iterator i=vmap->mapping.begin(); i!=vmap->mapping.end(); ++i) {                    (*new_map)[i->vert.index] = osg::Vec4(csf_->fix_point(osg::Vec3(i->value.at(0), i->value.at(1), i->value.at(2))), 0);                }            }        }        const lwo2::FORM::POLS *pols = dynamic_cast<const lwo2::FORM::POLS *>(*i);        if (pols && !current_layer.units().empty()) {            std::string type(pols->type.id, 4);            if (type != "FACE") {                osg::notify(osg::INFO) << "INFO: Lwo2Object: polygon list of type " << type << " not supported, rendering may be inaccurate" << std::endl;            }            for (lwo2::FORM::POLS::Polygon_list::const_iterator i=pols->polygons.begin(); i!=pols->polygons.end(); ++i) {                Polygon polygon;                bool must_invert_winding = csf_->invert_winding();                // FIX FOR A LIGHTWAVE BUG? MAYBE IT IS A FEATURE, I DON'T KNOW...                // if the first vertex is at a concave corner, we must invert the winding of the polygon                // beacuse it appears as flipped in Lighwave. Also, we tell the polygon to invert its normal.                // (not implemented yet)                /*if (i->vert.size() >= 4) {                    if (must_invert_winding == triangle_is_clockwise(current_layer.units().back().points(), i->vert.front().index, i->vert.back().index, i->vert[1].index)) {                        must_invert_winding = !must_invert_winding;                        polygon.set_invert_normal(true);                    }                }*/                if (must_invert_winding) {                    for (unsigned j=0; j<i->numvert; ++j) {                        int index = i->vert.at((i->numvert-j)%i->numvert).index;                        polygon.indices().push_back(index);                        current_layer.units().back().shares().at(index).push_back(current_layer.units().back().polygons().size());                    }                } else {                    for (unsigned j=0; j<i->numvert; ++j) {                        int index = i->vert.at(j).index;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -