Merged Pavel's updates to LWO2 for handle multiple texture layers.
This commit is contained in:
@@ -41,7 +41,6 @@
|
||||
|
||||
Lwo2::Lwo2():
|
||||
_current_layer(0),
|
||||
_geode(0),
|
||||
_successfully_read(false)
|
||||
{
|
||||
}
|
||||
@@ -83,28 +82,26 @@ Lwo2::ReadFile( const string& filename )
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(INFO) << "Detected EA-IFF85 format" << std::endl;
|
||||
notify(NOTICE) << "Detected EA-IFF85 format" << std::endl;
|
||||
}
|
||||
|
||||
unsigned long form_size = _read_long();
|
||||
notify(DEBUG_INFO) << "Form size: " << form_size << std::endl;
|
||||
notify(INFO) << "Form size: " << form_size << std::endl;
|
||||
|
||||
// checking LWO2 format
|
||||
// http://www.lightwave3d.com/developer/75lwsdk/docs/filefmts/lwo2.html
|
||||
if (_read_long() != tag_LWO2)
|
||||
{
|
||||
unsigned long make_id(const char*);
|
||||
notify(DEBUG_INFO) << "File '" << filename << "' is not LWO2 format file." << std::endl;
|
||||
notify(NOTICE) << "File '" << filename << "' is not LWO2 format file." << std::endl;
|
||||
_fin.close();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(INFO) << "Detected LWO2 format" << std::endl;
|
||||
notify(NOTICE) << "Detected LWO2 format" << std::endl;
|
||||
}
|
||||
|
||||
_geode = osgNew osg::Geode();
|
||||
|
||||
unsigned long read_bytes = 4;
|
||||
unsigned long current_tag_name;
|
||||
unsigned long current_tag_size;
|
||||
@@ -119,43 +116,43 @@ Lwo2::ReadFile( const string& filename )
|
||||
|
||||
if (current_tag_name == tag_TAGS)
|
||||
{
|
||||
_read_tag_strings(current_tag_size);
|
||||
_read_tag_strings(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_LAYR)
|
||||
{
|
||||
_read_layer(current_tag_size);
|
||||
_read_layer(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_PNTS)
|
||||
{
|
||||
_read_points(current_tag_size);
|
||||
_read_points(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_VMAP)
|
||||
{
|
||||
_read_vertex_mapping(current_tag_size);
|
||||
_read_vertex_mapping(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_VMAD)
|
||||
{
|
||||
_read_polygons_mapping(current_tag_size);
|
||||
_read_polygons_mapping(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_POLS)
|
||||
{
|
||||
_read_polygons(current_tag_size);
|
||||
_read_polygons(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_PTAG)
|
||||
{
|
||||
_read_polygon_tag_mapping(current_tag_size);
|
||||
_read_polygon_tag_mapping(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_CLIP)
|
||||
{
|
||||
_read_image_definition(current_tag_size);
|
||||
_read_image_definition(current_tag_size);
|
||||
}
|
||||
else if (current_tag_name == tag_SURF)
|
||||
{
|
||||
_read_surface(current_tag_size);
|
||||
_read_surface(current_tag_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,23 +221,23 @@ Lwo2::_read_string(string& str)
|
||||
void
|
||||
Lwo2::_print_tag(unsigned int tag, unsigned int size) {
|
||||
notify(DEBUG_INFO) << "Found tag "
|
||||
<< char(tag >> 24)
|
||||
<< char(tag >> 16)
|
||||
<< char(tag >> 8)
|
||||
<< char(tag)
|
||||
<< " size " << size << " bytes"
|
||||
<< std::endl;
|
||||
<< char(tag >> 24)
|
||||
<< char(tag >> 16)
|
||||
<< char(tag >> 8)
|
||||
<< char(tag)
|
||||
<< " size " << size << " bytes"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// print 4-char type
|
||||
void
|
||||
Lwo2::_print_type(unsigned int type) {
|
||||
notify(DEBUG_INFO) << " type \t"
|
||||
<< char(type >> 24)
|
||||
<< char(type >> 16)
|
||||
<< char(type >> 8)
|
||||
<< char(type)
|
||||
<< std::endl;
|
||||
<< char(type >> 24)
|
||||
<< char(type >> 16)
|
||||
<< char(type >> 8)
|
||||
<< char(type)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// read TAGS info
|
||||
@@ -302,51 +299,16 @@ Lwo2::_read_points(unsigned long size)
|
||||
|
||||
while (count--)
|
||||
{
|
||||
float x = _read_float();
|
||||
float y = _read_float();
|
||||
float z = _read_float();
|
||||
_current_layer->_points.push_back(Vec3(x, y,z));
|
||||
PointData point;
|
||||
|
||||
float x = _read_float();
|
||||
float y = _read_float();
|
||||
float z = _read_float();
|
||||
point.coord = Vec3(x, y, z);
|
||||
_current_layer->_points.push_back(point);
|
||||
}
|
||||
}
|
||||
|
||||
// read POLS info
|
||||
|
||||
void
|
||||
Lwo2::_read_polygons(unsigned long size)
|
||||
{
|
||||
unsigned int type = _read_long();
|
||||
size -= 4;
|
||||
|
||||
_print_type(type);
|
||||
|
||||
if (type == tag_FACE)
|
||||
{
|
||||
unsigned short vertex_count;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
vertex_count = _read_short() & 0x03FF;
|
||||
size -= 2;
|
||||
|
||||
PointsList* points_list = osgNew PointsList;
|
||||
_current_layer->_polygons.push_back(points_list);
|
||||
|
||||
while (vertex_count--)
|
||||
{
|
||||
points_list->push_back(_read_short());
|
||||
size -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// not recognized yet
|
||||
notify(DEBUG_INFO) << " skipping..." << std::endl;
|
||||
_fin.seekg(size + size % 2, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
// read VMAP info
|
||||
|
||||
void
|
||||
@@ -370,18 +332,100 @@ Lwo2::_read_vertex_mapping(unsigned long size)
|
||||
if (type == tag_TXUV && dimension == 2)
|
||||
{
|
||||
int count = size / 10;
|
||||
_current_layer->_points_map.resize(count);
|
||||
|
||||
short n;
|
||||
unsigned short n;
|
||||
float u;
|
||||
float v;
|
||||
while (count--)
|
||||
{
|
||||
n = _read_short();
|
||||
u = _read_float();
|
||||
v = _read_float();
|
||||
_current_layer->_points_map[n].set(u, v);
|
||||
}
|
||||
{
|
||||
n = _read_short();
|
||||
u = _read_float();
|
||||
v = _read_float();
|
||||
|
||||
// point coords must be read previously
|
||||
if (n < _current_layer->_points.size())
|
||||
{
|
||||
_current_layer->_points[n].texcoord = Vec2(u, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// not recognized yet
|
||||
notify(DEBUG_INFO) << " skipping..." << std::endl;
|
||||
_fin.seekg(size + size % 2, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
// read POLS info
|
||||
|
||||
void
|
||||
Lwo2::_read_polygons(unsigned long size)
|
||||
{
|
||||
unsigned int type = _read_long();
|
||||
size -= 4;
|
||||
|
||||
_print_type(type);
|
||||
|
||||
if (type == tag_FACE)
|
||||
{
|
||||
unsigned short vertex_count;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
PointData point;
|
||||
vertex_count = _read_short() & 0x03FF;
|
||||
size -= 2;
|
||||
|
||||
PointsList points_list;
|
||||
|
||||
while (vertex_count--)
|
||||
{
|
||||
unsigned short point_index = _read_short();
|
||||
|
||||
point = _current_layer->_points[point_index];
|
||||
point.point_index = point_index;
|
||||
|
||||
points_list.push_back(point);
|
||||
size -= 2;
|
||||
}
|
||||
|
||||
_current_layer->_polygons.push_back(points_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// not recognized yet
|
||||
notify(DEBUG_INFO) << " skipping..." << std::endl;
|
||||
_fin.seekg(size + size % 2, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
// read PTAG info
|
||||
|
||||
void
|
||||
Lwo2::_read_polygon_tag_mapping(unsigned long size)
|
||||
{
|
||||
unsigned int type = _read_long();
|
||||
size -= 4;
|
||||
|
||||
_print_type(type);
|
||||
|
||||
if (type == tag_SURF)
|
||||
{
|
||||
int count = size / 4;
|
||||
_current_layer->_polygons_tag.resize(count);
|
||||
|
||||
short polygon_index;
|
||||
short tag_index;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
polygon_index = _read_short();
|
||||
tag_index = _read_short();
|
||||
_current_layer->_polygons_tag[polygon_index] = tag_index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -390,7 +434,6 @@ Lwo2::_read_vertex_mapping(unsigned long size)
|
||||
notify(DEBUG_INFO) << " skipping..." << std::endl;
|
||||
_fin.seekg(size + size % 2, ios::cur);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// read VMAD info
|
||||
@@ -415,24 +458,35 @@ Lwo2::_read_polygons_mapping(unsigned long size)
|
||||
|
||||
if (type == tag_TXUV && dimension == 2)
|
||||
{
|
||||
notify(DEBUG_INFO) << " polygons mappings:" << endl;
|
||||
notify(DEBUG_INFO) << "\tpoint\tpolygon\ttexcoord" << endl;
|
||||
notify(DEBUG_INFO) << "\t=====\t=======\t========" << endl;
|
||||
|
||||
int count = size / 12;
|
||||
// _current_layer->_points_map.resize(count);
|
||||
|
||||
short point_index;
|
||||
short polygon_index;
|
||||
float u;
|
||||
float v;
|
||||
while (count--)
|
||||
{
|
||||
point_index = _read_short();
|
||||
polygon_index = _read_short();
|
||||
u = _read_float();
|
||||
v = _read_float();
|
||||
{
|
||||
point_index = _read_short();
|
||||
polygon_index = _read_short();
|
||||
u = _read_float();
|
||||
v = _read_float();
|
||||
|
||||
Lwo2PolygonMapping pm(polygon_index, Vec2(u, v));
|
||||
_current_layer->_polygons_map.insert(PairVMAD(point_index, pm));
|
||||
notify(DEBUG_INFO) << " \t" << point_index << "\t" << polygon_index << "\t" << Vec2(u, v) << endl;
|
||||
|
||||
}
|
||||
// apply texture coordinates
|
||||
PointsList& points_list = _current_layer->_polygons[polygon_index];
|
||||
for (unsigned int i = 0; i < points_list.size(); i++)
|
||||
{
|
||||
if (points_list[i].point_index == point_index)
|
||||
{
|
||||
points_list[i].texcoord = Vec2(u, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -444,40 +498,6 @@ Lwo2::_read_polygons_mapping(unsigned long size)
|
||||
|
||||
}
|
||||
|
||||
// read PTAG info
|
||||
|
||||
void
|
||||
Lwo2::_read_polygon_tag_mapping(unsigned long size)
|
||||
{
|
||||
unsigned int type = _read_long();
|
||||
size -= 4;
|
||||
|
||||
_print_type(type);
|
||||
|
||||
if (type == tag_SURF)
|
||||
{
|
||||
int count = size / 4;
|
||||
_current_layer->_polygons_tag.resize(count);
|
||||
|
||||
short polygon_index;
|
||||
short tag_index;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
polygon_index = _read_short();
|
||||
tag_index = _read_short();
|
||||
_current_layer->_polygons_tag[polygon_index] = tag_index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// not recognized yet
|
||||
notify(DEBUG_INFO) << " skipping..." << std::endl;
|
||||
_fin.seekg(size + size % 2, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
// read CLIP info
|
||||
|
||||
void
|
||||
@@ -505,9 +525,9 @@ Lwo2::_read_image_definition(unsigned long size)
|
||||
size -= name.length() + name.length() % 2;
|
||||
|
||||
if (index + 1 > _images.size())
|
||||
{
|
||||
_images.resize(index + 1);
|
||||
}
|
||||
{
|
||||
_images.resize(index + 1);
|
||||
}
|
||||
|
||||
_images[index] = name.c_str();
|
||||
|
||||
@@ -546,77 +566,77 @@ Lwo2::_read_surface(unsigned long size)
|
||||
_print_tag(current_tag_name, current_tag_size);
|
||||
|
||||
if (current_tag_name == tag_BLOK)
|
||||
{
|
||||
{
|
||||
|
||||
// BLOK
|
||||
int blok_size = current_tag_size;
|
||||
size -= blok_size;
|
||||
while (blok_size > 0)
|
||||
{
|
||||
current_tag_name = _read_long();
|
||||
blok_size -= 4;
|
||||
current_tag_size = _read_short();
|
||||
blok_size -= 2;
|
||||
notify(DEBUG_INFO) << " ";
|
||||
_print_tag(current_tag_name, current_tag_size);
|
||||
// BLOK
|
||||
int blok_size = current_tag_size;
|
||||
size -= blok_size;
|
||||
while (blok_size > 0)
|
||||
{
|
||||
current_tag_name = _read_long();
|
||||
blok_size -= 4;
|
||||
current_tag_size = _read_short();
|
||||
blok_size -= 2;
|
||||
notify(DEBUG_INFO) << " ";
|
||||
_print_tag(current_tag_name, current_tag_size);
|
||||
|
||||
if (current_tag_name == tag_IMAG)
|
||||
{
|
||||
surface->image_index = _read_short();
|
||||
notify(DEBUG_INFO) << " image index\t" << surface->image_index << std::endl;
|
||||
blok_size -= 2;
|
||||
}
|
||||
else if (current_tag_name == tag_IMAP)
|
||||
{
|
||||
if (current_tag_name == tag_IMAG)
|
||||
{
|
||||
surface->image_index = _read_short();
|
||||
notify(DEBUG_INFO) << " image index\t" << surface->image_index << std::endl;
|
||||
blok_size -= 2;
|
||||
}
|
||||
else if (current_tag_name == tag_IMAP)
|
||||
{
|
||||
|
||||
// IMAP
|
||||
int imap_size = current_tag_size;
|
||||
blok_size -= imap_size;
|
||||
// IMAP
|
||||
int imap_size = current_tag_size;
|
||||
blok_size -= imap_size;
|
||||
|
||||
string ordinal;
|
||||
_read_string(ordinal);
|
||||
imap_size -= ordinal.length() + ordinal.length() % 2;
|
||||
notify(DEBUG_INFO) << " ordinal \t'" << ordinal.c_str() << "'" << std::endl;
|
||||
string ordinal;
|
||||
_read_string(ordinal);
|
||||
imap_size -= ordinal.length() + ordinal.length() % 2;
|
||||
notify(DEBUG_INFO) << " ordinal \t'" << ordinal.c_str() << "'" << std::endl;
|
||||
|
||||
while(imap_size > 0)
|
||||
{
|
||||
current_tag_name = _read_long();
|
||||
imap_size -= 4;
|
||||
current_tag_size = _read_short();
|
||||
imap_size -= 2;
|
||||
notify(DEBUG_INFO) << " ";
|
||||
_print_tag(current_tag_name, current_tag_size);
|
||||
while(imap_size > 0)
|
||||
{
|
||||
current_tag_name = _read_long();
|
||||
imap_size -= 4;
|
||||
current_tag_size = _read_short();
|
||||
imap_size -= 2;
|
||||
notify(DEBUG_INFO) << " ";
|
||||
_print_tag(current_tag_name, current_tag_size);
|
||||
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
imap_size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
blok_size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
imap_size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
blok_size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (current_tag_name == tag_COLR)
|
||||
{
|
||||
float r = _read_float();
|
||||
float g = _read_float();
|
||||
float b = _read_float();
|
||||
surface->color.set(r,g,b);
|
||||
{
|
||||
float r = _read_float();
|
||||
float g = _read_float();
|
||||
float b = _read_float();
|
||||
surface->color.set(r,g,b);
|
||||
notify(DEBUG_INFO) << " color \t" << surface->color << std::endl;
|
||||
current_tag_size -= 12;
|
||||
size -= 12;
|
||||
current_tag_size -= 12;
|
||||
size -= 12;
|
||||
|
||||
// skip ununderstooded envelope
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
// skip ununderstooded envelope
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
{
|
||||
_fin.seekg(current_tag_size + current_tag_size % 2, ios::cur);
|
||||
size -= current_tag_size + current_tag_size % 2;
|
||||
}
|
||||
}
|
||||
|
||||
_surfaces[surface->name] = surface;
|
||||
@@ -634,15 +654,22 @@ Lwo2::GenerateGroup( Group& group )
|
||||
|
||||
// create geometry from all layers
|
||||
for (IteratorLayers itr = _layers.begin(); itr != _layers.end(); itr++)
|
||||
// IteratorLayers itr = _layers.begin();
|
||||
// itr++;
|
||||
// itr++;
|
||||
{
|
||||
osg::Geode* geode = osgNew osg::Geode();
|
||||
(*itr).second->GenerateGeode(*geode, _tags.size());
|
||||
|
||||
notify(DEBUG_INFO) << "Generate geode for layer " << (*itr).first << std::endl;
|
||||
DrawableToTagMapping tag_mapping;
|
||||
(*itr).second->GenerateGeode(*geode, _tags.size(), tag_mapping);
|
||||
|
||||
// assign StateSet for each PTAG group
|
||||
for (unsigned int i = 0; i < geode->getNumDrawables(); i++)
|
||||
{
|
||||
geode->getDrawable(i)->setStateSet(_surfaces[_tags[i]]->state_set);
|
||||
}
|
||||
{
|
||||
notify(DEBUG_INFO) << " Assigning surface " << _tags[tag_mapping[i]] << " to drawable " << i << std::endl;
|
||||
geode->getDrawable(i)->setStateSet(_surfaces[_tags[tag_mapping[i]]]->state_set);
|
||||
}
|
||||
|
||||
group.addChild(geode);
|
||||
}
|
||||
@@ -659,26 +686,28 @@ Lwo2::_generate_statesets_from_surfaces()
|
||||
Lwo2Surface* surface = (*itr_surf).second;
|
||||
StateSet* state_set = osgNew osg::StateSet;
|
||||
|
||||
notify(DEBUG_INFO) << "\tcreating surface " << (*itr_surf).first << std::endl;
|
||||
|
||||
// check if exist texture image for this surface
|
||||
if (surface->image_index >= 0)
|
||||
{
|
||||
notify(DEBUG_INFO) << "\tloading image '" << _images[surface->image_index] << "'" << std::endl;
|
||||
Image* image = osgDB::readImageFile(_images[surface->image_index]);
|
||||
notify(DEBUG_INFO) << "\tresult - " << image << std::endl;
|
||||
if (image)
|
||||
{
|
||||
Texture2D* texture = osgNew osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
state_set->setTextureAttributeAndModes(0, texture, StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
{
|
||||
Image* image = osgDB::readImageFile(_images[surface->image_index]);
|
||||
notify(DEBUG_INFO) << "\tloaded image '" << _images[surface->image_index] << "'" << std::endl;
|
||||
notify(DEBUG_INFO) << "\tresult - " << image << std::endl;
|
||||
if (image)
|
||||
{
|
||||
Texture2D* texture = osgNew osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
state_set->setTextureAttributeAndModes(0, texture, StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
|
||||
// set color
|
||||
Material* material = osgNew Material();
|
||||
Vec4 color(surface->color[0],
|
||||
surface->color[1],
|
||||
surface->color[2],
|
||||
1.0f);
|
||||
surface->color[1],
|
||||
surface->color[2],
|
||||
1.0f);
|
||||
material->setDiffuse(Material::FRONT_AND_BACK, color);
|
||||
state_set->setAttribute(material);
|
||||
|
||||
@@ -688,6 +717,8 @@ Lwo2::_generate_statesets_from_surfaces()
|
||||
state_set->setAttribute(cull);
|
||||
state_set->setMode(GL_CULL_FACE, StateAttribute::ON);
|
||||
|
||||
state_set->setMode(GL_NORMALIZE, StateAttribute::ON);
|
||||
|
||||
surface->state_set = state_set;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ class Lwo2Layer;
|
||||
struct Lwo2Surface;
|
||||
struct Lwo2PolygonMapping;
|
||||
|
||||
typedef vector< short > PointsList;
|
||||
|
||||
typedef vector< string >::iterator IteratorString;
|
||||
typedef map< int, Lwo2Layer* >::iterator IteratorLayers;
|
||||
typedef map< string, Lwo2Surface* >::iterator IteratorSurfaces;
|
||||
@@ -67,7 +65,6 @@ class Lwo2
|
||||
vector< string > _tags;
|
||||
vector< string > _images;
|
||||
ifstream _fin;
|
||||
Geode* _geode;
|
||||
|
||||
unsigned char _read_char();
|
||||
unsigned short _read_short();
|
||||
|
||||
@@ -34,13 +34,6 @@ Lwo2Layer::Lwo2Layer():
|
||||
|
||||
Lwo2Layer::~Lwo2Layer()
|
||||
{
|
||||
|
||||
// deleting points lists
|
||||
IteratorPointsList pol_itr;
|
||||
for (pol_itr = _polygons.begin(); pol_itr != _polygons.end(); pol_itr++)
|
||||
{
|
||||
osgDelete (*pol_itr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,36 +48,33 @@ Lwo2Layer::notify(NotifySeverity severity)
|
||||
|
||||
// points
|
||||
osg::notify(severity) << " points:\t" << _points.size() << endl;
|
||||
IteratorVec3 itr;
|
||||
osg::notify(severity) << "\tcoord\t\t\t\ttexcoord" << endl;
|
||||
osg::notify(severity) << "\t=====\t\t\t\t========" << endl;
|
||||
IteratorPoint itr;
|
||||
for (itr = _points.begin(); itr != _points.end(); itr++)
|
||||
{
|
||||
osg::notify(severity) << " \t" << (*itr) << endl;
|
||||
}
|
||||
|
||||
// points mappings
|
||||
osg::notify(severity) << " points mappings:\t" << _points_map.size() << endl;
|
||||
IteratorVec2 itr_vec2;
|
||||
for (itr_vec2 = _points_map.begin(); itr_vec2 != _points_map.end(); itr_vec2++)
|
||||
{
|
||||
osg::notify(severity) << " \t" << (*itr_vec2) << endl;
|
||||
osg::notify(severity) << " \t" << (*itr).coord << "\t\t" << (*itr).texcoord << endl;
|
||||
}
|
||||
|
||||
// polygons
|
||||
osg::notify(severity) << " polygons:\t" << _polygons.size() << endl;
|
||||
IteratorPointsList pol_itr;
|
||||
IteratorShort short_itr;
|
||||
for (pol_itr = _polygons.begin(); pol_itr != _polygons.end(); pol_itr++)
|
||||
osg::notify(severity) << "\tcoord\t\t\t\ttexcoord" << endl;
|
||||
osg::notify(severity) << "\t=====\t\t\t\t========" << endl;
|
||||
IteratorPolygonsList polygon_iterator;
|
||||
int polygon_index = 0;
|
||||
for (polygon_iterator = _polygons.begin(); polygon_iterator != _polygons.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
osg::notify(severity) << " " << (*pol_itr)->size() << ":";
|
||||
for (short_itr = (*pol_itr)->begin(); short_itr != (*pol_itr)->end(); short_itr++)
|
||||
{
|
||||
osg::notify(severity) << "\t" << (*short_itr);
|
||||
}
|
||||
osg::notify(severity) << " \t" << polygon_index << " ("<< (*polygon_iterator).size() << " vertexes" << "):" << endl;
|
||||
for (itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
|
||||
{
|
||||
osg::notify(severity) << " \t" << (*itr).coord << "\t\t" << (*itr).texcoord << endl;
|
||||
}
|
||||
osg::notify(severity) << endl;
|
||||
}
|
||||
|
||||
// polygons tags
|
||||
osg::notify(severity) << " polygons tags:\t" << _polygons_tag.size() << endl;
|
||||
IteratorShort short_itr;
|
||||
for (short_itr = _polygons_tag.begin(); short_itr != _polygons_tag.end(); short_itr++)
|
||||
{
|
||||
osg::notify(severity) << "\t" << (*short_itr) << endl;
|
||||
@@ -92,13 +82,18 @@ Lwo2Layer::notify(NotifySeverity severity)
|
||||
}
|
||||
|
||||
void
|
||||
Lwo2Layer::GenerateGeode( Geode& geode, short tags_count )
|
||||
Lwo2Layer::GenerateGeode( Geode& geode, short tags_count, DrawableToTagMapping& tag_mapping)
|
||||
{
|
||||
notify(DEBUG_INFO);
|
||||
|
||||
// variable used to track using textures
|
||||
bool have_texture_coords;
|
||||
|
||||
// create diffirent geomerty for each tag
|
||||
for (short current_tag = 0; current_tag < tags_count; current_tag++)
|
||||
{
|
||||
have_texture_coords = false;
|
||||
|
||||
// new geometry
|
||||
ref_ptr<Geometry> geometry = osgNew Geometry;
|
||||
|
||||
@@ -108,77 +103,340 @@ Lwo2Layer::GenerateGeode( Geode& geode, short tags_count )
|
||||
// create texture array
|
||||
ref_ptr<Vec2Array> texcoords = osgNew Vec2Array;
|
||||
|
||||
// variables for VMAD data processing
|
||||
pair<multimap< short, Lwo2PolygonMapping >::iterator,
|
||||
multimap< short, Lwo2PolygonMapping >::iterator> range;
|
||||
multimap< short, Lwo2PolygonMapping >::iterator itr;
|
||||
|
||||
// all polygons
|
||||
// selecting polygons for current layer only
|
||||
int polygon_index = 0;
|
||||
for (IteratorPointsList pol_itr = _polygons.begin(); pol_itr != _polygons.end(); pol_itr++, polygon_index++)
|
||||
{
|
||||
PolygonsList polygons;
|
||||
for (IteratorPolygonsList polygon_iterator = _polygons.begin(); polygon_iterator != _polygons.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
// *polygon_iterator it's a PolygonsList
|
||||
|
||||
// polygons of current tag only
|
||||
if (_polygons_tag[polygon_index] == current_tag)
|
||||
{
|
||||
// polygons of current tag only
|
||||
if (_polygons_tag[polygon_index] == current_tag)
|
||||
{
|
||||
|
||||
// all points
|
||||
vector< short >::iterator short_itr;
|
||||
for (short_itr = (*pol_itr)->begin(); short_itr != (*pol_itr)->end(); short_itr++)
|
||||
{
|
||||
// reset point_index member for later comparing poins data
|
||||
PointsList points_list = *polygon_iterator;
|
||||
for (unsigned int i = 0; i < points_list.size(); i++)
|
||||
{
|
||||
points_list[i].point_index = 0;
|
||||
}
|
||||
|
||||
// polygons coords
|
||||
(*coords).push_back(_points[*short_itr]);
|
||||
polygons.push_back(*polygon_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// point texture coords
|
||||
if (_points_map.size() > 0)
|
||||
{
|
||||
// VMAP data
|
||||
Vec2 uv = _points_map[*short_itr];
|
||||
// find and compose triangle fans
|
||||
PolygonsList triangle_fans;
|
||||
_find_triangle_fans(polygons, triangle_fans);
|
||||
|
||||
// chech if present VMAD data
|
||||
if (_polygons_map.size() > 0)
|
||||
{
|
||||
// find and compose triangle strips
|
||||
PolygonsList triangle_strips;
|
||||
_find_triangle_strips(polygons, triangle_strips);
|
||||
|
||||
// select data for current point
|
||||
range = _polygons_map.equal_range(*short_itr);
|
||||
// polygons of current layer
|
||||
polygon_index = 0;
|
||||
for (IteratorPolygonsList polygon_iterator = polygons.begin(); polygon_iterator != polygons.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
if ((*polygon_iterator)[0].point_index != -1)
|
||||
{
|
||||
// all points of polygon
|
||||
for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
|
||||
{
|
||||
// *itr - it's a PointData
|
||||
|
||||
for (itr = range.first; itr != range.second; itr++)
|
||||
{
|
||||
// polygons data
|
||||
(*coords).push_back((*itr).coord);
|
||||
(*texcoords).push_back((*itr).texcoord);
|
||||
|
||||
// found current polygon
|
||||
if ((*itr).second.polygon_index == polygon_index)
|
||||
{
|
||||
uv = (*itr).second.uv;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
|
||||
{
|
||||
have_texture_coords = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
|
||||
unsigned int points_count = (*polygon_iterator).size();
|
||||
if (points_count == 3)
|
||||
{
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::TRIANGLES, points_start, points_count));
|
||||
}
|
||||
else if (points_count == 4)
|
||||
{
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::QUADS, points_start, points_count));
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::POLYGON, points_start, points_count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*texcoords).push_back(uv);
|
||||
}
|
||||
}
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::POLYGON,
|
||||
(*coords).size() - (*pol_itr)->size(),
|
||||
(*pol_itr)->size()));
|
||||
}
|
||||
}
|
||||
// triangle fans of current layer
|
||||
polygon_index = 0;
|
||||
for (IteratorPolygonsList polygon_iterator = triangle_fans.begin(); polygon_iterator != triangle_fans.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
|
||||
// all points of polygon
|
||||
for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
|
||||
{
|
||||
// *itr - it's a PointData
|
||||
|
||||
// polygons data
|
||||
(*coords).push_back((*itr).coord);
|
||||
(*texcoords).push_back((*itr).texcoord);
|
||||
|
||||
if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
|
||||
{
|
||||
have_texture_coords = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
|
||||
unsigned int points_count = (*polygon_iterator).size();
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::TRIANGLE_FAN, points_start, points_count));
|
||||
}
|
||||
|
||||
// triangle strips of current layer
|
||||
polygon_index = 0;
|
||||
for (IteratorPolygonsList polygon_iterator = triangle_strips.begin(); polygon_iterator != triangle_strips.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
|
||||
// all points of polygon
|
||||
for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
|
||||
{
|
||||
// *itr - it's a PointData
|
||||
|
||||
// polygons data
|
||||
(*coords).push_back((*itr).coord);
|
||||
(*texcoords).push_back((*itr).texcoord);
|
||||
|
||||
if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
|
||||
{
|
||||
have_texture_coords = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
|
||||
unsigned int points_count = (*polygon_iterator).size();
|
||||
geometry->addPrimitiveSet(osgNew DrawArrays(PrimitiveSet::TRIANGLE_STRIP, points_start, points_count));
|
||||
}
|
||||
|
||||
// add geometry if it contains any points
|
||||
if (coords->size() != 0)
|
||||
{
|
||||
geometry->setVertexArray(coords.get());
|
||||
{
|
||||
geometry->setVertexArray(coords.get());
|
||||
|
||||
// assign texture array
|
||||
if ((*texcoords).size() > 0)
|
||||
{
|
||||
geometry->setTexCoordArray(0, texcoords.get());
|
||||
}
|
||||
// assign texture array
|
||||
if (have_texture_coords)
|
||||
{
|
||||
geometry->setTexCoordArray(0, texcoords.get());
|
||||
}
|
||||
|
||||
// generate normals
|
||||
osgUtil::SmoothingVisitor smoother;
|
||||
smoother.smooth(*(geometry.get()));
|
||||
// generate normals
|
||||
osgUtil::SmoothingVisitor smoother;
|
||||
smoother.smooth(*(geometry.get()));
|
||||
|
||||
geode.addDrawable(geometry.get());
|
||||
}
|
||||
geode.addDrawable(geometry.get());
|
||||
|
||||
osg::notify(DEBUG_INFO) << " inserting tag " << geode.getNumDrawables() - 1 << ":" << current_tag << std::endl;
|
||||
tag_mapping.insert(PairDrawableToTag(geode.getNumDrawables() - 1, current_tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Lwo2Layer::_find_triangle_fans(PolygonsList& polygons, PolygonsList& triangle_fans)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
while (_find_triangle_fan(polygons, triangle_fans))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (triangle_fans.size() > 0)
|
||||
{
|
||||
osg::notify(INFO) << "LWO2 loader, optimizing: found " << triangle_fans.size() << " triangle fans" << endl;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
Lwo2Layer::_find_triangle_strips(PolygonsList& polygons, PolygonsList& triangle_strips)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
while (_find_triangle_strip(polygons, triangle_strips))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (triangle_strips.size() > 0)
|
||||
{
|
||||
osg::notify(INFO) << "LWO2 loader, optimizing: found " << triangle_strips.size() << " triangle strips" << endl;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
Lwo2Layer::_find_triangle_fan(PolygonsList& polygons, PolygonsList& triangle_fans)
|
||||
{
|
||||
bool found = false;
|
||||
IteratorPolygonsList polygon_iterator = polygons.begin();
|
||||
while (polygon_iterator != polygons.end())
|
||||
{
|
||||
PointsList& points_list = *polygon_iterator;
|
||||
if (points_list.size() == 3 && points_list[0].point_index != -1)
|
||||
{
|
||||
PointData a = points_list[0];
|
||||
PointData b = points_list[1];
|
||||
PointData c = points_list[2];
|
||||
|
||||
int next_polygon_index = _find_triangle_begins_with(polygons, a, c);
|
||||
while (next_polygon_index >= 0)
|
||||
{
|
||||
found = true;
|
||||
PointData d = polygons[next_polygon_index][2];
|
||||
|
||||
PointsList point_list;
|
||||
point_list.push_back(a);
|
||||
point_list.push_back(b);
|
||||
point_list.push_back(c);
|
||||
point_list.push_back(d);
|
||||
|
||||
// delete second triangle (mark as deleted)
|
||||
(*(polygons.begin() + next_polygon_index))[0].point_index = -1;
|
||||
|
||||
// delete current (first) triangle (mark as deleted)
|
||||
(*polygon_iterator)[0].point_index = -1;
|
||||
|
||||
c = d;
|
||||
while ((next_polygon_index = _find_triangle_begins_with(polygons, a, c)) >= 0)
|
||||
{
|
||||
PointData d = polygons[next_polygon_index][2];
|
||||
point_list.push_back(d);
|
||||
|
||||
// delete next triangle (mark as deleted)
|
||||
(*(polygons.begin() + next_polygon_index))[0].point_index = -1;
|
||||
|
||||
c = d;
|
||||
}
|
||||
|
||||
triangle_fans.push_back(point_list);
|
||||
}
|
||||
}
|
||||
polygon_iterator++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
Lwo2Layer::_find_triangle_strip(PolygonsList& polygons, PolygonsList& triangle_strips)
|
||||
{
|
||||
bool found = false;
|
||||
IteratorPolygonsList polygon_iterator = polygons.begin();
|
||||
int polygon_index = 0;
|
||||
while (polygon_iterator != polygons.end())
|
||||
{
|
||||
PointsList& points_list = *polygon_iterator;
|
||||
if (points_list.size() == 3 && points_list[0].point_index != -1)
|
||||
{
|
||||
PointData a = points_list[0];
|
||||
PointData b = points_list[1];
|
||||
PointData c = points_list[2];
|
||||
|
||||
int next_polygon_index = _find_triangle_begins_with(polygons, c, b);
|
||||
|
||||
while (next_polygon_index >= 0)
|
||||
{
|
||||
found = true;
|
||||
PointData d = polygons[next_polygon_index][2];
|
||||
|
||||
PointsList point_list;
|
||||
point_list.push_back(a);
|
||||
point_list.push_back(b);
|
||||
point_list.push_back(c);
|
||||
point_list.push_back(d);
|
||||
|
||||
// delete second triangle (mark as deleted)
|
||||
(*(polygons.begin() + next_polygon_index))[0].point_index = -1;
|
||||
|
||||
// delete current (first) triangle (mark as deleted)
|
||||
(*polygon_iterator)[0].point_index = -1;
|
||||
|
||||
PointData strip_a = c;
|
||||
PointData strip_b = d;
|
||||
bool current_strip_a = true;
|
||||
|
||||
while ((next_polygon_index = _find_triangle_begins_with(polygons, strip_a, strip_b)) >= 0)
|
||||
{
|
||||
PointData d = polygons[next_polygon_index][2];
|
||||
point_list.push_back(d);
|
||||
|
||||
if (current_strip_a)
|
||||
{
|
||||
strip_a = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
strip_b = d;
|
||||
}
|
||||
current_strip_a = !current_strip_a;
|
||||
|
||||
// delete next triangle (mark as deleted)
|
||||
(*(polygons.begin() + next_polygon_index))[0].point_index = -1;
|
||||
}
|
||||
|
||||
triangle_strips.push_back(point_list);
|
||||
}
|
||||
}
|
||||
polygon_iterator++;
|
||||
polygon_index++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int
|
||||
Lwo2Layer::_find_triangle_begins_with(PolygonsList& polygons, PointData& a, PointData& b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
int polygon_index = 0;
|
||||
for (IteratorPolygonsList polygon_iterator = polygons.begin(); polygon_iterator != polygons.end(); polygon_iterator++, polygon_index++)
|
||||
{
|
||||
PointsList& points_list = *polygon_iterator;
|
||||
if (points_list.size() == 3 && points_list[0].point_index != -1)
|
||||
{
|
||||
if (points_list[0] == a && points_list[1] == b)
|
||||
{
|
||||
result = polygon_index;
|
||||
break;
|
||||
}
|
||||
else if (points_list[1] == a && points_list[2] == b)
|
||||
{
|
||||
// shift points
|
||||
PointData temp = points_list[0];
|
||||
points_list[0] = points_list[1];
|
||||
points_list[1] = points_list[2];
|
||||
points_list[2] = temp;
|
||||
|
||||
result = polygon_index;
|
||||
break;
|
||||
}
|
||||
else if (points_list[2] == a && points_list[0] == b)
|
||||
{
|
||||
// shift points
|
||||
PointData temp = points_list[2];
|
||||
points_list[2] = points_list[1];
|
||||
points_list[1] = points_list[0];
|
||||
points_list[0] = temp;
|
||||
|
||||
result = polygon_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#ifndef LWO2LAYER_H
|
||||
#define LWO2LAYER_H 1
|
||||
#define LWO2LAYER_H
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/Vec2>
|
||||
@@ -42,12 +42,23 @@
|
||||
using namespace osg;
|
||||
using namespace std;
|
||||
|
||||
typedef vector< short > PointsList;
|
||||
struct PointData
|
||||
{
|
||||
PointData():
|
||||
point_index(0),
|
||||
coord(Vec3(0.0f, 0.0f, 0.0f)),
|
||||
texcoord(Vec2(-1.0f, -1.0f)) {}
|
||||
|
||||
typedef vector< PointsList* >::iterator IteratorPointsList;
|
||||
typedef vector< Vec3 >::iterator IteratorVec3;
|
||||
typedef vector< Vec2 >::iterator IteratorVec2;
|
||||
typedef vector< short >::iterator IteratorShort;
|
||||
short point_index;
|
||||
Vec3 coord;
|
||||
Vec2 texcoord;
|
||||
|
||||
inline bool operator == (const PointData& p) const
|
||||
{
|
||||
return coord == p.coord && texcoord == p.texcoord;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Lwo2Surface
|
||||
{
|
||||
@@ -61,15 +72,16 @@ struct Lwo2Surface
|
||||
StateSet* state_set;
|
||||
};
|
||||
|
||||
struct Lwo2PolygonMapping
|
||||
{
|
||||
Lwo2PolygonMapping(short s, const Vec2& v2):
|
||||
polygon_index(s),
|
||||
uv(v2) {}
|
||||
|
||||
short polygon_index;
|
||||
Vec2 uv;
|
||||
};
|
||||
typedef vector< PointData > PointsList;
|
||||
typedef vector< PointsList > PolygonsList;
|
||||
typedef PolygonsList::iterator IteratorPolygonsList;
|
||||
|
||||
typedef map< int, int > DrawableToTagMapping;
|
||||
typedef pair< int, int > PairDrawableToTag;
|
||||
|
||||
typedef vector< PointData >::iterator IteratorPoint;
|
||||
typedef vector< Vec2 >::iterator IteratorVec2;
|
||||
typedef vector< short >::iterator IteratorShort;
|
||||
|
||||
class Lwo2Layer
|
||||
{
|
||||
@@ -78,19 +90,23 @@ class Lwo2Layer
|
||||
Lwo2Layer();
|
||||
~Lwo2Layer();
|
||||
void notify(NotifySeverity);
|
||||
void GenerateGeode( Geode&, short );
|
||||
void GenerateGeode( Geode&, short, DrawableToTagMapping& );
|
||||
|
||||
private:
|
||||
bool _find_triangle_fans(PolygonsList&, PolygonsList&);
|
||||
bool _find_triangle_fan(PolygonsList&, PolygonsList&);
|
||||
bool _find_triangle_strips(PolygonsList&, PolygonsList&);
|
||||
bool _find_triangle_strip(PolygonsList&, PolygonsList&);
|
||||
int _find_triangle_begins_with(PolygonsList&, PointData&, PointData&);
|
||||
|
||||
short _number;
|
||||
short _flags;
|
||||
short _parent;
|
||||
Vec3 _pivot;
|
||||
string _name;
|
||||
vector< Vec3 > _points;
|
||||
vector< Vec2 > _points_map;
|
||||
vector< PointsList* > _polygons;
|
||||
vector< PointData > _points;
|
||||
PolygonsList _polygons;
|
||||
vector< short > _polygons_tag;
|
||||
multimap< short, Lwo2PolygonMapping > _polygons_map;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user