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::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 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; } }