Exemple #1
0
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_);
        }
    }
}
Exemple #2
0
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);
        }
    }
}
Exemple #3
0
void Block::read_common_attributes(const iff::Chunk_list &subchunks)
{
    for (iff::Chunk_list::const_iterator i=subchunks.begin(); i!=subchunks.end(); ++i) {
        const lwo2::FORM::SURF::BLOK::CHAN *chan = dynamic_cast<const lwo2::FORM::SURF::BLOK::CHAN *>(*i);
        if (chan) {
            channel_ = std::string(chan->texture_channel.id, 4);
        }
        const lwo2::FORM::SURF::BLOK::ENAB *enab = dynamic_cast<const lwo2::FORM::SURF::BLOK::ENAB *>(*i);
        if (enab) {
            enabled_ = enab->enable != 0;
        }
        const lwo2::FORM::SURF::BLOK::OPAC *opac = dynamic_cast<const lwo2::FORM::SURF::BLOK::OPAC *>(*i);
        if (opac) {
            opacity_type_ = static_cast<Opacity_type>(opac->type);
            opacity_amount_ = opac->opacity.fraction;
        }
        const lwo2::FORM::SURF::BLOK::AXIS *axis = dynamic_cast<const lwo2::FORM::SURF::BLOK::AXIS *>(*i);
        if (axis) {
            displacement_axis_ = static_cast<Axis_type>(axis->displacement_axis);
        }
    }
}
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_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_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_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_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_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_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_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_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
                // because 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;
                        polygon.indices().push_back(index);
                        current_layer.units().back().shares().at(index).push_back(current_layer.units().back().polygons().size());
                    }
                }

                current_layer.units().back().polygons().push_back(polygon);
            }
        }

        const lwo2::FORM::TAGS *tags = dynamic_cast<const lwo2::FORM::TAGS*>(*i);
        if (tags)
        {
            tag_strings = tags->tag_string;
        }

        const lwo2::FORM::PTAG *ptag = dynamic_cast<const lwo2::FORM::PTAG*>(*i);
        if (ptag && !current_layer.units().empty())
        {
            std::string type(ptag->type.id, 4);
            if (type == "SURF")
            {
                for (lwo2::FORM::PTAG::Mapping_list::const_iterator i = ptag->mapping.begin(); i != ptag->mapping.end(); ++i)
                {
                    current_layer.units().back().polygons().at(i->poly.index).set_surface(&surfaces_[tag_strings.at(i->tag)]);
                }
            }

            if (type == "PART")
            {
                for (lwo2::FORM::PTAG::Mapping_list::const_iterator i = ptag->mapping.begin(); i != ptag->mapping.end(); ++i)
                {
                    current_layer.units().back().polygons().at(i->poly.index).set_part_name(tag_strings.at(i->tag));
                }
            }

            if (type == "SMGP")
            {
                for (lwo2::FORM::PTAG::Mapping_list::const_iterator i = ptag->mapping.begin(); i != ptag->mapping.end(); ++i)
                {
                    current_layer.units().back().polygons().at(i->poly.index).set_smoothing_group(tag_strings.at(i->tag));
                }
            }
        }

        const lwo2::FORM::VMAD *vmad = dynamic_cast<const lwo2::FORM::VMAD*>(*i);
        if (vmad && !current_layer.units().empty())
        {
            std::string type(vmad->type.id, 4);
            if (type == "WGHT")
            {
                if (vmad->dimension != 1)
                {
                    OSG_WARN << "Warning: Lwo2Object: invalid " << type << " discontinuous vertex map dimension: " << vmad->dimension << std::endl;
                    continue;
                }

                for (lwo2::FORM::VMAD::Mapping_list::const_iterator i = vmad->mapping.begin(); i != vmad->mapping.end(); ++i)
                {
                    VertexMap *this_map = current_layer.units().back().polygons().at(i->poly.index).weight_maps()->getOrCreate(vmad->name);
                    (*this_map)[i->vert.index] = osg::Vec4(i->value.at(0), 0, 0, 0);
                }
            }

            if (type == "TXUV")
            {
                if (vmad->dimension != 2)
                {
                    OSG_WARN << "Warning: Lwo2Object: invalid " << type << " discontinuous vertex map dimension: " << vmad->dimension << std::endl;
                    continue;
                }

                for (lwo2::FORM::VMAD::Mapping_list::const_iterator i = vmad->mapping.begin(); i != vmad->mapping.end(); ++i)
                {
                    VertexMap *this_map = current_layer.units().back().polygons().at(i->poly.index).texture_maps()->getOrCreate(vmad->name);
                    (*this_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), 0, 0);
                }
            }

            if (type == "RGB ")
            {
                if (vmad->dimension != 3)
                {
                    OSG_WARN << "Warning: Lwo2Object: invalid " << type << " discontinuous vertex map dimension: " << vmad->dimension << std::endl;
                    continue;
                }

                for (lwo2::FORM::VMAD::Mapping_list::const_iterator i = vmad->mapping.begin(); i != vmad->mapping.end(); ++i)
                {
                    VertexMap *this_map = current_layer.units().back().polygons().at(i->poly.index).rgb_maps()->getOrCreate(vmad->name);
                    (*this_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), i->value.at(2), 1);
                }
            }

            if (type == "RGBA")
            {
                if (vmad->dimension != 4)
                {
                    OSG_WARN << "Warning: Lwo2Object: invalid " << type << " discontinuous vertex map dimension: " << vmad->dimension << std::endl;
                    continue;
                }

                for (lwo2::FORM::VMAD::Mapping_list::const_iterator i = vmad->mapping.begin(); i != vmad->mapping.end(); ++i)
                {
                    VertexMap *this_map = current_layer.units().back().polygons().at(i->poly.index).rgba_maps()->getOrCreate(vmad->name);
                    (*this_map)[i->vert.index] = osg::Vec4(i->value.at(0), i->value.at(1), i->value.at(2), i->value.at(3));
                }
            }
        }

        const lwo2::FORM::DESC *desc = dynamic_cast<const lwo2::FORM::DESC*>(*i);
        if (desc)
        {
            description_ = desc->description_line;
        }

        const lwo2::FORM::TEXT *text = dynamic_cast<const lwo2::FORM::TEXT*>(*i);
        if (text)
        {
            comment_ = text->comment;
        }
    }

    if (!current_layer.units().empty() || current_layer.get_layer_chunk())
    {
        layers_[current_layer.number()] = current_layer;
    }
}