📄 lwo2mesh.cpp
字号:
for (unsigned int j = 0; j < point->polygons.size(); j++)
{
lwPolygon *polygon = point->polygons[j];
if (polygon->type == polygontype)
if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
{
destpoints.push_back(point);
break;
}
}
}
}
void Lwo2MeshWriter::copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons)
{
for (unsigned int i = 0; i < sourcepolygons.size(); i++)
{
lwPolygon *polygon = sourcepolygons[i];
if (polygon->type == polygontype)
if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
destpolygons.push_back(polygon);
}
}
void Lwo2MeshWriter::copyDataToVertexData(vpoints &points,
vpolygons &polygons,
vvmaps &vmaps,
IndexData *indexData,
VertexData *vertexData,
unsigned short vertexDataOffset)
{
lwVMap *vmap = 0;
unsigned int ni;
HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
Real* pPos = static_cast<Real*>(pbuf->lock(HardwareBuffer::HBL_DISCARD));
Real* pNor = static_cast<Real*>(nbuf->lock(HardwareBuffer::HBL_DISCARD));
Real* pTex = static_cast<Real*>(tbuf->lock(HardwareBuffer::HBL_DISCARD));
unsigned short *pIdx = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
for (unsigned int p = 0; p < polygons.size(); p++)
{
lwPolygon *polygon = polygons[p];
if (polygon->vertices.size() != 3) continue; // only copy triangles;
for (unsigned int v = 0; v < polygon->vertices.size(); v++)
{
lwVertex *vertex = polygon->vertices[v];
lwPoint *point = vertex->point;
unsigned short i = getPointIndex(point, points);
pIdx[p*3 + v] = vertexDataOffset + i;
ni = (vertexDataOffset + i) * 3;
pPos[ni] = vertex->point->x;
pPos[ni + 1] = vertex->point->y;
pPos[ni + 2] = vertex->point->z;
pNor[ni] = vertex->normal.x;
pNor[ni + 1] = vertex->normal.y;
pNor[ni + 2] = vertex->normal.z;
bool found = false;
ni = (vertexDataOffset + i) * 2;
for (unsigned int v = 0; v < point->vmaps.size(); v++)
{
for (unsigned int vr = 0; vr < vmaps.size(); vr++)
{
vmap = vmaps[vr];
if (point->vmaps[v].vmap == vmap)
{
int n = point->vmaps[v].index;
pTex[ni] = vmap->val[n][0];
pTex[ni + 1] = 1.0f - vmap->val[n][1];
found = true;
break;
}
}
if (found) break;
}
}
}
pbuf->unlock();
nbuf->unlock();
tbuf->unlock();
ibuf->unlock();
}
void Lwo2MeshWriter::prepLwObject(void)
{
unsigned int l, p;
for (l = 0; l < object->layers.size(); l++)
{
lwLayer *layer = object->layers[l];
#ifdef _DEBUG
cout << "Triangulating layer " << l << ", Polygons before: " << layer->polygons.size();
#endif
layer->triangulatePolygons();
#ifdef _DEBUG
cout << ", Polygons after: " << layer->polygons.size() << endl;
#endif
// Mirror x-coord for Ogre;
for (p = 0; p < layer->points.size(); p++)
{
layer->points[p]->x *= -1.0f;
layer->points[p]->polygons.clear();
}
// Unscrew the bounding box
float x = layer->bboxmin.x * -1.0f;
layer->bboxmin.x = layer->bboxmax.x * -1.0f;
layer->bboxmax.x = x;
for ( p = 0; p < layer->polygons.size(); p++ )
{
lwPolygon *polygon = layer->polygons[ p ];
for (unsigned int j = 0; j < polygon->vertices.size(); j++ )
polygon->vertices[ j ]->point->polygons.push_back(polygon);
}
for (p = 0; p < layer->polygons.size(); p++)
layer->polygons[p]->flip();
layer->calculatePolygonNormals();
layer->calculateVertexNormals();
}
}
inline int Lwo2MeshWriter::getPointIndex(lwPoint *point, vpoints &points)
{
for (unsigned int i = 0; i < points.size(); ++i)
if (points[i] == point) return i;
return -1;
}
inline String Lwo2MeshWriter::makeLayerFileName(char* dest, unsigned int l, char *layername)
{
char
drive[ _MAX_DRIVE ],
dir[ _MAX_DIR ],
node[ _MAX_FNAME ],
ext[ _MAX_EXT ],
buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
String LayerFileName;
String TempName;
_splitpath( dest, drive, dir, node, ext );
TempName = String( node );
if (layername) {
TempName += ".";
TempName += layername;
} else {
TempName += ".layer" + StringConverter::toString(l);
}
_makepath( buf, drive, dir, TempName.c_str(), ext );
LayerFileName = String( buf );
return LayerFileName;
}
inline String Lwo2MeshWriter::makeMaterialFileName(char* dest)
{
char
drive[ _MAX_DRIVE ],
dir[ _MAX_DIR ],
node[ _MAX_FNAME ],
ext[ _MAX_EXT ],
buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
String MaterialFileName;
_splitpath( dest, drive, dir, node, ext );
_makepath( buf, drive, dir, node, ".material" );
const char *test = MaterialFileName.c_str();
MaterialFileName = String( buf );
return MaterialFileName;
}
inline void Lwo2MeshWriter::getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps)
{
for (unsigned int i = 0; i < textures.size(); i++)
{
lwTexture *texture = textures[i];
if (texture->type == ID_IMAP && texture->param.imap)
{
char *mapname = texture->param.imap->vmap_name;
if (mapname)
for (unsigned int v = 0; v < svmaps.size(); v++)
{
lwVMap *vmap = svmaps[v];
if (strcmp(mapname, vmap->name) == 0) dvmaps.push_back(vmap);
}
}
}
return;
}
bool Lwo2MeshWriter::writeLwo2Mesh(lwObject *nobject, char *ndest)
{
object = nobject;
dest = ndest;
if (!object) return false;
if (!object->layers.size()) return false;
LogManager::getSingleton().createLog("Lwo2MeshWriter.log");
prepLwObject();
vpoints points;
vpolygons polygons;
vvmaps vmaps;
MeshSerializer meshserializer;
if (flags[ExportMaterials])
{
doExportMaterials();
materialSerializer->exportQueued(makeMaterialFileName(dest));
}
unsigned int ml = object->layers.size();
bool SeparateLayers = flags[UseSeparateLayers] && ml > 1;
if (!SeparateLayers) ogreMesh = new Mesh(ndest);
Ogre::Vector3 boundingBoxMin(FLT_MAX, FLT_MAX, FLT_MAX);
Ogre::Vector3 boundingBoxMax(FLT_MIN, FLT_MIN, FLT_MIN);
for( unsigned int ol = 0; ol < ml; ++ol )
{
if (!object->layers[ol]->polygons.size())
continue;
Ogre::Vector3 currentMin(object->layers[ol]->bboxmin.x,
object->layers[ol]->bboxmin.y,
object->layers[ol]->bboxmin.z);
Ogre::Vector3 currentMax(object->layers[ol]->bboxmax.x,
object->layers[ol]->bboxmax.y,
object->layers[ol]->bboxmax.z);
if (SeparateLayers)
{
ogreMesh = new Mesh(ndest);
ogreMesh->_setBounds(Ogre::AxisAlignedBox(currentMin, currentMax));
ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(currentMin.squaredLength(), currentMax.squaredLength())));
}
else
{
boundingBoxMin.makeFloor(currentMin);
boundingBoxMax.makeCeil(currentMax);
}
for (unsigned int s = 0; s < object->surfaces.size(); s++)
{
lwSurface *surface = object->surfaces[s];
points.clear();
polygons.clear();
vmaps.clear();
unsigned int l = ol;
for( unsigned int il = 0; il < ml; ++il )
{
if (!SeparateLayers) l = il;
copyPoints(s, ID_FACE, object->layers[l]->points, points);
copyPolygons(s, ID_FACE, object->layers[l]->polygons, polygons);
getTextureVMaps(surface->color.textures, object->layers[l]->vmaps, vmaps);
if (SeparateLayers) break;
}
if (!polygons.size()) continue;
SubMesh *ogreSubMesh = ogreMesh->createSubMesh();
ogreSubMesh->useSharedVertices = flags[UseSharedVertexData] && points.size() < POINTLIMIT;
ogreSubMesh->indexData->indexCount = polygons.size() * 3;
ogreSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
ogreSubMesh->setMaterialName(surface->name);
if (ogreSubMesh->useSharedVertices)
{
unsigned short vertexDataOffset = 0;
if (ogreMesh->sharedVertexData) vertexDataOffset = ogreMesh->sharedVertexData->vertexCount;
ogreMesh->sharedVertexData = setupVertexData(points.size(), ogreMesh->sharedVertexData);
copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreMesh->sharedVertexData, vertexDataOffset);
}
else
{
ogreSubMesh->vertexData = setupVertexData(points.size());
copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreSubMesh->vertexData);
}
}
if (!SeparateLayers)
{
ogreMesh->_setBounds(Ogre::AxisAlignedBox(boundingBoxMin, boundingBoxMax));
ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(boundingBoxMin.squaredLength(), boundingBoxMax.squaredLength())));
}
String fname = SeparateLayers ? makeLayerFileName(dest, ol, object->layers[ol]->name) : dest;
Skeleton *skeleton = 0;
if (flags[ExportSkeleton])
if (SeparateLayers)
skeleton = doExportSkeleton(fname, ol);
else
if (!ol) skeleton = doExportSkeleton(fname, -1);
if (flags[GenerateLOD])
{
ProgressiveMesh::VertexReductionQuota quota;
if (flags[UseFixedMethod])
quota = ProgressiveMesh::VRQ_CONSTANT;
else
quota = ProgressiveMesh::VRQ_PROPORTIONAL;
ogreMesh->generateLodLevels(distanceList, quota, reduction);
}
try
{
meshserializer.exportMesh(ogreMesh, fname);
}
catch (...)
{
cout << "Could not export to file: " << fname << endl;
}
ogreMesh->unload();
delete ogreMesh;
if (flags[ExportSkeleton] && skeleton) delete skeleton;
if (!SeparateLayers) break;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -