LWO
- added workaround for LWOB's with ill-formed SURF chunks - layer hierarchy is now correct - fixed & simplified transparency handling FindDegenerates - fixed seldom crashes with RemoveDegenerates=1. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@369 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
74204086ae
commit
48d768f15f
|
@ -142,13 +142,6 @@ void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to update the primitive flags array of the mesh.
|
// We need to update the primitive flags array of the mesh.
|
||||||
// Unfortunately it is not possible to execute
|
|
||||||
// FindDegenerates before DeterminePType. The latter does
|
|
||||||
// nothing if the primitive flags have already been set by
|
|
||||||
// the loader - our changes would be ignored. Although
|
|
||||||
// we could use some tricks regarding - i.e setting
|
|
||||||
// mPrimitiveTypes to 0 in every case - but this is the cleanest
|
|
||||||
// way and causes no additional dependencies in the pipeline.
|
|
||||||
switch (face.mNumIndices)
|
switch (face.mNumIndices)
|
||||||
{
|
{
|
||||||
case 1u:
|
case 1u:
|
||||||
|
@ -181,9 +174,11 @@ evil_jump_outside:
|
||||||
face_dest.mNumIndices = face_src.mNumIndices;
|
face_dest.mNumIndices = face_src.mNumIndices;
|
||||||
face_dest.mIndices = face_src.mIndices;
|
face_dest.mIndices = face_src.mIndices;
|
||||||
|
|
||||||
// clear source
|
if (&face_src != &face_dest) {
|
||||||
face_src.mNumIndices = 0;
|
// clear source
|
||||||
face_src.mIndices = NULL;
|
face_src.mNumIndices = 0;
|
||||||
|
face_src.mIndices = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Otherwise delete it if we don't need this face
|
// Otherwise delete it if we don't need this face
|
||||||
|
|
|
@ -379,11 +379,11 @@ Importer::Importer()
|
||||||
mPostProcessingSteps.push_back( new FindInstancesProcess());
|
mPostProcessingSteps.push_back( new FindInstancesProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (!defined AI_BUILD_NO_FINDDEGENERATES_PROCESS)
|
#if (!defined AI_BUILD_NO_FINDDEGENERATES_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new FindDegeneratesProcess());
|
mPostProcessingSteps.push_back( new FindDegeneratesProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef AI_BUILD_NO_GENUVCOORDS_PROCESS
|
#ifndef AI_BUILD_NO_GENUVCOORDS_PROCESS
|
||||||
mPostProcessingSteps.push_back( new ComputeUVMappingProcess());
|
mPostProcessingSteps.push_back( new ComputeUVMappingProcess());
|
||||||
|
@ -398,6 +398,7 @@ Importer::Importer()
|
||||||
#if (!defined AI_BUILD_NO_TRIANGULATE_PROCESS)
|
#if (!defined AI_BUILD_NO_TRIANGULATE_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new TriangulateProcess());
|
mPostProcessingSteps.push_back( new TriangulateProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined AI_BUILD_NO_SORTBYPTYPE_PROCESS)
|
#if (!defined AI_BUILD_NO_SORTBYPTYPE_PROCESS)
|
||||||
mPostProcessingSteps.push_back( new SortByPTypeProcess());
|
mPostProcessingSteps.push_back( new SortByPTypeProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -229,14 +229,23 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||||
LWO::Texture* pTex = NULL;
|
LWO::Texture* pTex = NULL;
|
||||||
|
|
||||||
GetS0(surf.mName,size);
|
GetS0(surf.mName,size);
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
if (mFileBuffer + 6 >= end)
|
||||||
if (mFileBuffer + 6 > end)break;
|
break;
|
||||||
|
|
||||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||||
|
|
||||||
if (mFileBuffer + head->length > end)
|
/* A single test file (sonycam.lwo) seems to have invalid surface chunks.
|
||||||
throw new ImportErrorException("LWOB: Invalid surface chunk length");
|
* I'm assuming it's the fault of a single, unknown exporter so there are
|
||||||
|
* probably THOUSANDS of them. Here's a dirty workaround:
|
||||||
|
*
|
||||||
|
* We don't break if the chunk limit is exceeded. Instead, we're computing
|
||||||
|
* how much storage is actually left and work with this value from now on.
|
||||||
|
*/
|
||||||
|
if (mFileBuffer + head->length > end) {
|
||||||
|
DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
|
||||||
|
head->length = end - mFileBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* const next = mFileBuffer+head->length;
|
uint8_t* const next = mFileBuffer+head->length;
|
||||||
switch (head->type)
|
switch (head->type)
|
||||||
|
@ -340,8 +349,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||||
// texture path
|
// texture path
|
||||||
case AI_LWO_TIMG:
|
case AI_LWO_TIMG:
|
||||||
{
|
{
|
||||||
if (pTex)
|
if (pTex) {
|
||||||
{
|
|
||||||
GetS0(pTex->mFileName,head->length);
|
GetS0(pTex->mFileName,head->length);
|
||||||
}
|
}
|
||||||
else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
|
else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
|
||||||
|
@ -351,7 +359,9 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||||
case AI_LWO_TVAL:
|
case AI_LWO_TVAL:
|
||||||
{
|
{
|
||||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
|
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
|
||||||
if (pTex)pTex->mStrength = (float)GetU1()/ 255.f;
|
if (pTex) {
|
||||||
|
pTex->mStrength = (float)GetU1()/ 255.f;
|
||||||
|
}
|
||||||
else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
|
else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,7 +550,7 @@ struct Surface
|
||||||
, mIOR (1.f) // vakuum
|
, mIOR (1.f) // vakuum
|
||||||
, mBumpIntensity (1.f)
|
, mBumpIntensity (1.f)
|
||||||
, mWireframe (false)
|
, mWireframe (false)
|
||||||
, mAdditiveTransparency (10e10f)
|
, mAdditiveTransparency (0.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! Name of the surface
|
//! Name of the surface
|
||||||
|
@ -628,6 +628,7 @@ struct Layer
|
||||||
: mFaceIDXOfs (0)
|
: mFaceIDXOfs (0)
|
||||||
, mPointIDXOfs (0)
|
, mPointIDXOfs (0)
|
||||||
, mParent (0x0)
|
, mParent (0x0)
|
||||||
|
, mIndex (0xffff)
|
||||||
, skip (false)
|
, skip (false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -663,6 +664,9 @@ struct Layer
|
||||||
/** Parent index */
|
/** Parent index */
|
||||||
uint16_t mParent;
|
uint16_t mParent;
|
||||||
|
|
||||||
|
/** Index of the layer */
|
||||||
|
uint16_t mIndex;
|
||||||
|
|
||||||
/** Name of the layer */
|
/** Name of the layer */
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
|
|
|
@ -145,8 +145,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
mCurLayer->mName = "<LWODefault>";
|
mCurLayer->mName = "<LWODefault>";
|
||||||
|
|
||||||
// old lightwave file format (prior to v6)
|
// old lightwave file format (prior to v6)
|
||||||
if (AI_LWO_FOURCC_LWOB == fileType)
|
if (AI_LWO_FOURCC_LWOB == fileType) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
|
DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
|
||||||
|
|
||||||
mIsLWO2 = false;
|
mIsLWO2 = false;
|
||||||
|
@ -154,13 +153,11 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// New lightwave format
|
// New lightwave format
|
||||||
else if (AI_LWO_FOURCC_LWO2 == fileType)
|
else if (AI_LWO_FOURCC_LWO2 == fileType) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
|
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
|
||||||
}
|
}
|
||||||
// MODO file format
|
// MODO file format
|
||||||
else if (AI_LWO_FOURCC_LXOB == fileType)
|
else if (AI_LWO_FOURCC_LXOB == fileType) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
|
DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
|
||||||
}
|
}
|
||||||
// we don't know this format
|
// we don't know this format
|
||||||
|
@ -174,8 +171,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
throw new ImportErrorException(std::string("Unknown LWO sub format: ") + szBuff);
|
throw new ImportErrorException(std::string("Unknown LWO sub format: ") + szBuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AI_LWO_FOURCC_LWOB != fileType)
|
if (AI_LWO_FOURCC_LWOB != fileType) {
|
||||||
{
|
|
||||||
mIsLWO2 = true;
|
mIsLWO2 = true;
|
||||||
LoadLWO2File();
|
LoadLWO2File();
|
||||||
|
|
||||||
|
@ -185,8 +181,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
if (0xffffffff != configLayerIndex && configLayerIndex > mLayers->size())
|
if (0xffffffff != configLayerIndex && configLayerIndex > mLayers->size())
|
||||||
throw new ImportErrorException("LWO2: The requested layer was not found");
|
throw new ImportErrorException("LWO2: The requested layer was not found");
|
||||||
|
|
||||||
if (configLayerName.length() && !hasNamedLayer)
|
if (configLayerName.length() && !hasNamedLayer) {
|
||||||
{
|
|
||||||
throw new ImportErrorException("LWO2: Unable to find the requested layer: "
|
throw new ImportErrorException("LWO2: Unable to find the requested layer: "
|
||||||
+ configLayerName);
|
+ configLayerName);
|
||||||
}
|
}
|
||||||
|
@ -203,24 +198,21 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
|
apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
|
||||||
|
|
||||||
unsigned int iDefaultSurface = 0xffffffff; // index of the default surface
|
unsigned int iDefaultSurface = 0xffffffff; // index of the default surface
|
||||||
for (LayerList::iterator lit = mLayers->begin(), lend = mLayers->end();
|
for (LayerList::iterator lit = mLayers->begin(), lend = mLayers->end();lit != lend;++lit) {
|
||||||
lit != lend;++lit)
|
|
||||||
{
|
|
||||||
LWO::Layer& layer = *lit;
|
LWO::Layer& layer = *lit;
|
||||||
if (layer.skip)continue;
|
if (layer.skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
// I don't know whether there could be dummy layers, but it would be possible
|
// I don't know whether there could be dummy layers, but it would be possible
|
||||||
const unsigned int meshStart = (unsigned int)apcMeshes.size();
|
const unsigned int meshStart = (unsigned int)apcMeshes.size();
|
||||||
if (!layer.mFaces.empty() && !layer.mTempPoints.empty())
|
if (!layer.mFaces.empty() && !layer.mTempPoints.empty()) {
|
||||||
{
|
|
||||||
// now sort all faces by the surfaces assigned to them
|
// now sort all faces by the surfaces assigned to them
|
||||||
typedef std::vector<unsigned int> SortedRep;
|
typedef std::vector<unsigned int> SortedRep;
|
||||||
std::vector<SortedRep> pSorted(mSurfaces->size()+1);
|
std::vector<SortedRep> pSorted(mSurfaces->size()+1);
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end();
|
for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end();it != end;++it,++i) {
|
||||||
it != end;++it,++i)
|
|
||||||
{
|
|
||||||
// Check whether we support this face's type
|
// Check whether we support this face's type
|
||||||
if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH) {
|
if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -232,10 +224,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
DefaultLogger::get()->warn("LWO: Invalid face surface index");
|
DefaultLogger::get()->warn("LWO: Invalid face surface index");
|
||||||
idx = 0xffffffff;
|
idx = 0xffffffff;
|
||||||
}
|
}
|
||||||
if(0xffffffff == idx || 0xffffffff == (idx = _mMapping[idx]))
|
if(0xffffffff == idx || 0xffffffff == (idx = _mMapping[idx])) {
|
||||||
{
|
if (0xffffffff == iDefaultSurface) {
|
||||||
if (0xffffffff == iDefaultSurface)
|
|
||||||
{
|
|
||||||
iDefaultSurface = (unsigned int)mSurfaces->size();
|
iDefaultSurface = (unsigned int)mSurfaces->size();
|
||||||
mSurfaces->push_back(LWO::Surface());
|
mSurfaces->push_back(LWO::Surface());
|
||||||
LWO::Surface& surf = mSurfaces->back();
|
LWO::Surface& surf = mSurfaces->back();
|
||||||
|
@ -246,11 +236,13 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
pSorted[idx].push_back(i);
|
pSorted[idx].push_back(i);
|
||||||
}
|
}
|
||||||
if (0xffffffff == iDefaultSurface)pSorted.erase(pSorted.end()-1);
|
if (0xffffffff == iDefaultSurface) {
|
||||||
for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i)
|
pSorted.erase(pSorted.end()-1);
|
||||||
{
|
}
|
||||||
|
for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) {
|
||||||
SortedRep& sorted = pSorted[i];
|
SortedRep& sorted = pSorted[i];
|
||||||
if (sorted.empty())continue;
|
if (sorted.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
// generate the mesh
|
// generate the mesh
|
||||||
aiMesh* mesh = new aiMesh();
|
aiMesh* mesh = new aiMesh();
|
||||||
|
@ -259,8 +251,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// count the number of vertices
|
// count the number of vertices
|
||||||
SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
|
SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
|
||||||
for (;it != end;++it)
|
for (;it != end;++it) {
|
||||||
{
|
|
||||||
mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
|
mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,13 +276,13 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// allocate storage for UV and CV channels
|
// allocate storage for UV and CV channels
|
||||||
aiVector3D* pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
aiVector3D* pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui )
|
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
|
||||||
{
|
if (0xffffffff == vUVChannelIndices[mui])
|
||||||
if (0xffffffff == vUVChannelIndices[mui])break;
|
break;
|
||||||
|
|
||||||
pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
|
pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
|
||||||
|
|
||||||
// LightWave doesn't support more than 2 UV components (?)
|
// LightWave doesn't support more than 2 UV components (?)
|
||||||
// so we can directly setup this value
|
|
||||||
mesh->mNumUVComponents[0] = 2;
|
mesh->mNumUVComponents[0] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,15 +290,12 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
|
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
|
||||||
|
|
||||||
aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
|
aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||||
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui)
|
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui) {
|
||||||
{
|
|
||||||
if (0xffffffff == vVColorIndices[mui])break;
|
if (0xffffffff == vVColorIndices[mui])break;
|
||||||
pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
|
pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
|
||||||
}
|
}
|
||||||
|
|
||||||
// we would not need this extra array, but the code is much cleaner if we use it
|
// we would not need this extra array, but the code is much cleaner if we use it
|
||||||
// FIX: we can use the referrer ID array here. invalidate its contents
|
|
||||||
// before we resize it to avoid a unnecessary memcpy
|
|
||||||
std::vector<unsigned int>& smoothingGroups = layer.mPointReferrers;
|
std::vector<unsigned int>& smoothingGroups = layer.mPointReferrers;
|
||||||
smoothingGroups.erase (smoothingGroups.begin(),smoothingGroups.end());
|
smoothingGroups.erase (smoothingGroups.begin(),smoothingGroups.end());
|
||||||
smoothingGroups.resize(mesh->mNumFaces,0);
|
smoothingGroups.resize(mesh->mNumFaces,0);
|
||||||
|
@ -322,8 +310,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
// copy all vertices
|
// copy all vertices
|
||||||
for (unsigned int q = 0; q < face.mNumIndices;++q,++vert) {
|
for (unsigned int q = 0; q < face.mNumIndices;++q,++vert) {
|
||||||
register unsigned int idx = face.mIndices[q];
|
register unsigned int idx = face.mIndices[q];
|
||||||
*pv = layer.mTempPoints[idx] + layer.mPivot;
|
*pv++ = layer.mTempPoints[idx] /*- layer.mPivot*/;
|
||||||
pv++;
|
|
||||||
|
|
||||||
// process UV coordinates
|
// process UV coordinates
|
||||||
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w) {
|
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w) {
|
||||||
|
@ -338,7 +325,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// process normals (MODO extension)
|
// process normals (MODO extension)
|
||||||
if (nrm) {
|
if (nrm) {
|
||||||
*nrm++ = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
|
*nrm = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
|
||||||
|
nrm->z *= -1.f;
|
||||||
|
++nrm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process vertex colors
|
// process vertex colors
|
||||||
|
@ -365,15 +354,14 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
pf->mIndices = face.mIndices;
|
pf->mIndices = face.mIndices;
|
||||||
pf->mNumIndices = face.mNumIndices;
|
pf->mNumIndices = face.mNumIndices;
|
||||||
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // make sure it won't be deleted
|
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
|
||||||
pf++;
|
pf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mesh->mNormals)
|
if (!mesh->mNormals) {
|
||||||
{
|
|
||||||
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
|
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
|
||||||
// Step here since it wouldn't handle smoothing groups correctly for LWO.
|
// Step here since it wouldn't handle smoothing groups correctly for LWO.
|
||||||
// So we use a separate implementation.
|
// So we use a separate implementation.
|
||||||
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
|
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
|
||||||
}
|
}
|
||||||
else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
|
else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
|
||||||
|
@ -381,16 +369,21 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate nodes to render the mesh. Store the parent index
|
// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
|
||||||
// in the mParent member of the nodes
|
unsigned int num = apcMeshes.size() - meshStart;
|
||||||
aiNode* pcNode = new aiNode();
|
if (layer.mName != "<LWODefault>" || num > 0) {
|
||||||
apcNodes.push_back(pcNode);
|
aiNode* pcNode = new aiNode();
|
||||||
pcNode->mName.Set(layer.mName);
|
apcNodes.push_back(pcNode);
|
||||||
pcNode->mParent = (aiNode*)(uintptr_t)(layer.mParent);
|
pcNode->mName.Set(layer.mName);
|
||||||
pcNode->mNumMeshes = (unsigned int)apcMeshes.size() - meshStart;
|
pcNode->mParent = (aiNode*)&layer;
|
||||||
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
pcNode->mNumMeshes = num;
|
||||||
for (unsigned int p = 0; p < pcNode->mNumMeshes;++p)
|
|
||||||
pcNode->mMeshes[p] = p + meshStart;
|
if (pcNode->mNumMeshes) {
|
||||||
|
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
||||||
|
for (unsigned int p = 0; p < pcNode->mNumMeshes;++p)
|
||||||
|
pcNode->mMeshes[p] = p + meshStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apcNodes.empty() || apcMeshes.empty())
|
if (apcNodes.empty() || apcMeshes.empty())
|
||||||
|
@ -398,19 +391,16 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// The RemoveRedundantMaterials step will clean this up later
|
// The RemoveRedundantMaterials step will clean this up later
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
|
||||||
for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat)
|
for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat) {
|
||||||
{
|
|
||||||
MaterialHelper* pcMat = new MaterialHelper();
|
MaterialHelper* pcMat = new MaterialHelper();
|
||||||
pScene->mMaterials[mat] = pcMat;
|
pScene->mMaterials[mat] = pcMat;
|
||||||
ConvertMaterial((*mSurfaces)[mat],pcMat);
|
ConvertMaterial((*mSurfaces)[mat],pcMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the meshes to the output structure
|
// copy the meshes to the output structure
|
||||||
if (apcMeshes.size()) // shouldn't happen, just to be sure we don't crash
|
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ];
|
||||||
{
|
::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*));
|
||||||
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ];
|
|
||||||
::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*));
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate the final node graph
|
// generate the final node graph
|
||||||
GenerateNodeGraph(apcNodes);
|
GenerateNodeGraph(apcNodes);
|
||||||
|
@ -523,29 +513,36 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::AddChildren(aiNode* node, uintptr_t parent, std::vector<aiNode*>& apcNodes)
|
void LWOImporter::AddChildren(aiNode* node, uint16_t parent, std::vector<aiNode*>& apcNodes)
|
||||||
{
|
{
|
||||||
for (uintptr_t i = 0; i < (uintptr_t)apcNodes.size();++i)
|
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
||||||
{
|
if (*it) {
|
||||||
if (i == parent)continue;
|
LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
|
||||||
if (apcNodes[i] && (uintptr_t)apcNodes[i]->mParent == parent)++node->mNumChildren;
|
if (layer->mParent == parent && layer->mIndex != parent)
|
||||||
|
++node->mNumChildren;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->mNumChildren)
|
if (node->mNumChildren) {
|
||||||
{
|
unsigned int p = 0;
|
||||||
|
|
||||||
node->mChildren = new aiNode* [ node->mNumChildren ];
|
node->mChildren = new aiNode* [ node->mNumChildren ];
|
||||||
for (uintptr_t i = 0, p = 0; i < (uintptr_t)apcNodes.size();++i)
|
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
||||||
{
|
if (*it) {
|
||||||
if (i == parent)continue;
|
LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
|
||||||
|
if (layer->mParent == parent && layer->mIndex != parent) {
|
||||||
|
aiNode* nd = node->mChildren[p++] = *it;
|
||||||
|
nd->mParent = node;
|
||||||
|
|
||||||
if (apcNodes[i] && parent == (uintptr_t)(apcNodes[i]->mParent))
|
// fixme: ignore pivot points for the moment
|
||||||
{
|
//nd->mTransformation.a4 = layer->mPivot.x;
|
||||||
node->mChildren[p++] = apcNodes[i];
|
//nd->mTransformation.b4 = layer->mPivot.y;
|
||||||
apcNodes[i]->mParent = node;
|
//nd->mTransformation.c4 = layer->mPivot.z;
|
||||||
|
|
||||||
// recursively add more children
|
// recursively add more children
|
||||||
AddChildren(apcNodes[i],i,apcNodes);
|
(*it) = NULL;
|
||||||
apcNodes[i] = NULL;
|
AddChildren(nd,layer->mIndex,apcNodes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,43 +551,44 @@ void LWOImporter::AddChildren(aiNode* node, uintptr_t parent, std::vector<aiNode
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
|
void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
|
||||||
{
|
{
|
||||||
// now generate the final nodegraph - generate a root node
|
// now generate the final nodegraph - generate a root node and attach children
|
||||||
pScene->mRootNode = new aiNode();
|
aiNode* root = pScene->mRootNode = new aiNode();
|
||||||
pScene->mRootNode->mName.Set("<LWORoot>");
|
root->mName.Set("<LWORoot>");
|
||||||
AddChildren(pScene->mRootNode,0,apcNodes);
|
AddChildren(root,0,apcNodes);
|
||||||
|
|
||||||
|
// check whether we added all layers with meshes assigned to the output graph.
|
||||||
|
// if not, add them to the root node
|
||||||
unsigned int extra = 0;
|
unsigned int extra = 0;
|
||||||
for (unsigned int i = 0; i < apcNodes.size();++i)
|
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
||||||
if (apcNodes[i] && apcNodes[i]->mNumMeshes)++extra;
|
if ((*it) && (*it)->mNumMeshes)
|
||||||
|
++extra;
|
||||||
|
}
|
||||||
|
|
||||||
if (extra) {
|
if (extra) {
|
||||||
// we need to add extra nodes to the root
|
|
||||||
const unsigned int newSize = extra + pScene->mRootNode->mNumChildren;
|
const unsigned int newSize = extra + pScene->mRootNode->mNumChildren;
|
||||||
aiNode** const apcNewNodes = new aiNode*[newSize];
|
aiNode** const apcNewNodes = new aiNode*[newSize];
|
||||||
if((extra = pScene->mRootNode->mNumChildren))
|
if((extra = root->mNumChildren))
|
||||||
::memcpy(apcNewNodes,pScene->mRootNode->mChildren,extra*sizeof(void*));
|
::memcpy(apcNewNodes,root->mChildren,extra*sizeof(void*));
|
||||||
|
|
||||||
aiNode** cc = apcNewNodes+extra;
|
aiNode** cc = apcNewNodes+extra;
|
||||||
for (unsigned int i = 0; i < apcNodes.size();++i)
|
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
||||||
{
|
if ((*it) && (*it)->mNumMeshes) {
|
||||||
if (apcNodes[i] && apcNodes[i]->mNumMeshes)
|
aiNode* nd = *cc++ = *it;
|
||||||
{
|
nd->mParent = pScene->mRootNode;
|
||||||
*cc++ = apcNodes[i];
|
|
||||||
apcNodes[i]->mParent = pScene->mRootNode;
|
|
||||||
|
|
||||||
// recursively add more children
|
// recursively add more children
|
||||||
AddChildren(apcNodes[i],i,apcNodes);
|
(*it) = NULL;
|
||||||
apcNodes[i] = NULL;
|
AddChildren(nd,((LWO::Layer*)nd->mParent)->mIndex,apcNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] pScene->mRootNode->mChildren;
|
delete[] root->mChildren;
|
||||||
pScene->mRootNode->mChildren = apcNewNodes;
|
root->mChildren = apcNewNodes;
|
||||||
pScene->mRootNode->mNumChildren = newSize;
|
root->mNumChildren = newSize;
|
||||||
}
|
}
|
||||||
if (!pScene->mRootNode->mNumChildren)
|
if (!pScene->mRootNode->mNumChildren)
|
||||||
throw new ImportErrorException("LWO: Unable to build a valid node graph");
|
throw new ImportErrorException("LWO: Unable to build a valid node graph");
|
||||||
|
|
||||||
// Remove a single root node with no meshes assigned ...
|
// Remove a single root node with no meshes assigned to it ...
|
||||||
if (1 == pScene->mRootNode->mNumChildren) {
|
if (1 == pScene->mRootNode->mNumChildren) {
|
||||||
aiNode* pc = pScene->mRootNode->mChildren[0];
|
aiNode* pc = pScene->mRootNode->mChildren[0];
|
||||||
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
|
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
|
||||||
|
@ -802,7 +800,7 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else DefaultLogger::get()->warn("LWO2: face has 0 indices");
|
else throw new ImportErrorException("LWO2: face has 0 indices");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,9 +843,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
|
||||||
template <class T>
|
template <class T>
|
||||||
VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
|
VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
|
||||||
{
|
{
|
||||||
for (typename std::vector< T >::iterator it = list.begin(), end = list.end();
|
for (typename std::vector< T >::iterator it = list.begin(), end = list.end();it != end; ++it) {
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
if ((*it).name == name)
|
if ((*it).name == name)
|
||||||
{
|
{
|
||||||
if (!perPoly)
|
if (!perPoly)
|
||||||
|
@ -880,10 +876,7 @@ inline void CreateNewEntry(T& chan, unsigned int srcIdx)
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
|
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
|
||||||
{
|
{
|
||||||
for (typename std::vector< T >::iterator
|
for (typename std::vector< T >::iterator it = list.begin(), end = list.end();it != end;++it) {
|
||||||
it = list.begin(), end = list.end();
|
|
||||||
it != end;++it)
|
|
||||||
{
|
|
||||||
CreateNewEntry( *it, srcIdx );
|
CreateNewEntry( *it, srcIdx );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -907,8 +900,7 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
|
inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
|
||||||
{
|
{
|
||||||
if(0xffffffff == refList[srcIdx])
|
if(0xffffffff == refList[srcIdx]) {
|
||||||
{
|
|
||||||
refList[srcIdx] = destIdx;
|
refList[srcIdx] = destIdx;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -992,20 +984,16 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
|
||||||
while (mFileBuffer < end)
|
while (mFileBuffer < end)
|
||||||
{
|
{
|
||||||
unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
|
unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
|
||||||
if (idx >= numPoints)
|
if (idx >= numPoints) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->warn("LWO2: vertex index in vmap/vmad is out of range");
|
DefaultLogger::get()->warn("LWO2: vertex index in vmap/vmad is out of range");
|
||||||
mFileBuffer += base->dims*4;continue;
|
mFileBuffer += base->dims*4;continue;
|
||||||
}
|
}
|
||||||
if (perPoly)
|
if (perPoly) {
|
||||||
{
|
|
||||||
unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
|
unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
|
||||||
if (base->abAssigned[idx])
|
if (base->abAssigned[idx]) {
|
||||||
{
|
|
||||||
// we have already a VMAP entry for this vertex - thus
|
// we have already a VMAP entry for this vertex - thus
|
||||||
// we need to duplicate the corresponding polygon.
|
// we need to duplicate the corresponding polygon.
|
||||||
if (polyIdx >= numFaces)
|
if (polyIdx >= numFaces) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range");
|
DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range");
|
||||||
mFileBuffer += base->dims*4;
|
mFileBuffer += base->dims*4;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1015,10 +1003,10 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
|
||||||
|
|
||||||
// generate a new unique vertex for the corresponding index - but only
|
// generate a new unique vertex for the corresponding index - but only
|
||||||
// if we can find the index in the face
|
// if we can find the index in the face
|
||||||
for (unsigned int i = 0; i < src.mNumIndices;++i)
|
for (unsigned int i = 0; i < src.mNumIndices;++i) {
|
||||||
{
|
|
||||||
register unsigned int srcIdx = src.mIndices[i];
|
register unsigned int srcIdx = src.mIndices[i];
|
||||||
if (idx != srcIdx)continue;
|
if (idx != srcIdx)
|
||||||
|
continue;
|
||||||
|
|
||||||
refList.resize(refList.size()+1, 0xffffffff);
|
refList.resize(refList.size()+1, 0xffffffff);
|
||||||
|
|
||||||
|
@ -1245,22 +1233,24 @@ void LWOImporter::LoadLWO2File()
|
||||||
LWO::Layer& layer = mLayers->back();
|
LWO::Layer& layer = mLayers->back();
|
||||||
mCurLayer = &layer;
|
mCurLayer = &layer;
|
||||||
|
|
||||||
// load this layer or ignore it? Check the layer index property
|
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
|
||||||
// NOTE: The first layer is the default layer, so the layer
|
|
||||||
// index is one-based now
|
// Continue loading this layer or ignore it? Check the layer index property
|
||||||
|
// NOTE: The first layer is the default layer, so the layer index is one-based now
|
||||||
if (0xffffffff != configLayerIndex && configLayerIndex != mLayers->size()-1) {
|
if (0xffffffff != configLayerIndex && configLayerIndex != mLayers->size()-1) {
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
else skip = false;
|
else skip = false;
|
||||||
|
|
||||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
|
// layer index. that's just for internal parenting, from the scope of a LWS file
|
||||||
|
// all layers are numbered in the oder in which they appear in the file
|
||||||
|
layer.mIndex = GetU2();
|
||||||
|
|
||||||
// and parse its properties, e.g. the pivot point
|
// pivot point
|
||||||
mFileBuffer += 2;
|
mFileBuffer += 2; /* unknown */
|
||||||
mCurLayer->mPivot.x = GetF4();
|
mCurLayer->mPivot.x = GetF4();
|
||||||
mCurLayer->mPivot.y = GetF4();
|
mCurLayer->mPivot.y = GetF4();
|
||||||
mCurLayer->mPivot.z = GetF4();
|
mCurLayer->mPivot.z = GetF4();
|
||||||
mFileBuffer += 2;
|
|
||||||
GetS0(layer.mName,head->length-16);
|
GetS0(layer.mName,head->length-16);
|
||||||
|
|
||||||
// if the name is empty, generate a default name
|
// if the name is empty, generate a default name
|
||||||
|
@ -1276,6 +1266,7 @@ void LWOImporter::LoadLWO2File()
|
||||||
}
|
}
|
||||||
else hasNamedLayer = true;
|
else hasNamedLayer = true;
|
||||||
|
|
||||||
|
// optional: parent of this layer
|
||||||
if (mFileBuffer + 2 <= next)
|
if (mFileBuffer + 2 <= next)
|
||||||
layer.mParent = GetU2();
|
layer.mParent = GetU2();
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,7 @@ private:
|
||||||
* @param parent Index of the node
|
* @param parent Index of the node
|
||||||
* @param apcNodes Flat list of nodes - used nodes are set to NULL.
|
* @param apcNodes Flat list of nodes - used nodes are set to NULL.
|
||||||
*/
|
*/
|
||||||
void AddChildren(aiNode* node, uintptr_t parent,
|
void AddChildren(aiNode* node, uint16_t parent,
|
||||||
std::vector<aiNode*>& apcNodes);
|
std::vector<aiNode*>& apcNodes);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -90,10 +90,9 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a
|
||||||
aiString s;
|
aiString s;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (TextureList::const_iterator it = in.begin(), end = in.end();
|
for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it) {
|
||||||
it != end;++it)
|
if (!(*it).enabled || !(*it).bCanUse)
|
||||||
{
|
continue;
|
||||||
if (!(*it).enabled || !(*it).bCanUse)continue;
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
// Convert lightwave's mapping modes to ours. We let them
|
// Convert lightwave's mapping modes to ours. We let them
|
||||||
|
@ -121,8 +120,7 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a
|
||||||
break;
|
break;
|
||||||
case LWO::Texture::UV:
|
case LWO::Texture::UV:
|
||||||
{
|
{
|
||||||
if( 0xffffffff == (*it).mRealUVIndex )
|
if( 0xffffffff == (*it).mRealUVIndex ) {
|
||||||
{
|
|
||||||
// We have no UV index for this texture, so we can't display it
|
// We have no UV index for this texture, so we can't display it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -166,13 +164,11 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a
|
||||||
|
|
||||||
// The older LWOB format does not use indirect references to clips.
|
// The older LWOB format does not use indirect references to clips.
|
||||||
// The file name of a texture is directly specified in the tex chunk.
|
// The file name of a texture is directly specified in the tex chunk.
|
||||||
if (mIsLWO2)
|
if (mIsLWO2) {
|
||||||
{
|
|
||||||
// find the corresponding clip
|
// find the corresponding clip
|
||||||
ClipList::iterator clip = mClips.begin();
|
ClipList::iterator clip = mClips.begin();
|
||||||
temp = (*it).mClipIdx;
|
temp = (*it).mClipIdx;
|
||||||
for (ClipList::iterator end = mClips.end(); clip != end; ++clip)
|
for (ClipList::iterator end = mClips.end(); clip != end; ++clip) {
|
||||||
{
|
|
||||||
if ((*clip).idx == temp)
|
if ((*clip).idx == temp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -284,8 +280,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
|
||||||
if (surf.mSpecularValue && surf.mGlossiness)
|
if (surf.mSpecularValue && surf.mGlossiness)
|
||||||
{
|
{
|
||||||
float fGloss;
|
float fGloss;
|
||||||
if (mIsLWO2)
|
if (mIsLWO2) {
|
||||||
{
|
|
||||||
fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
|
fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -314,7 +309,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
|
||||||
pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
|
pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
|
||||||
|
|
||||||
// opacity ... either additive or default-blended, please
|
// opacity ... either additive or default-blended, please
|
||||||
if (10e10f != surf.mAdditiveTransparency)
|
if (0.f != surf.mAdditiveTransparency)
|
||||||
{
|
{
|
||||||
const int add = aiBlendMode_Additive;
|
const int add = aiBlendMode_Additive;
|
||||||
pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
|
pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
|
||||||
|
@ -437,12 +432,9 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, const LWO::Layer& lay
|
||||||
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
|
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
|
||||||
{
|
{
|
||||||
out[0] = 0xffffffff;
|
out[0] = 0xffffffff;
|
||||||
if (surf.mVCMap.length())
|
if (surf.mVCMap.length()) {
|
||||||
{
|
for (unsigned int i = 0; i < layer.mVColorChannels.size();++i) {
|
||||||
for (unsigned int i = 0; i < layer.mVColorChannels.size();++i)
|
if (surf.mVCMap == layer.mVColorChannels[i].name) {
|
||||||
{
|
|
||||||
if (surf.mVCMap == layer.mVColorChannels[i].name)
|
|
||||||
{
|
|
||||||
out[0] = i;
|
out[0] = i;
|
||||||
out[1] = 0xffffffff;
|
out[1] = 0xffffffff;
|
||||||
return;
|
return;
|
||||||
|
@ -598,11 +590,8 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
// now attach the texture to the parent surface - sort by ordinal string
|
// now attach the texture to the parent surface - sort by ordinal string
|
||||||
for (TextureList::iterator it = listRef->begin();
|
for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it) {
|
||||||
it != listRef->end(); ++it)
|
if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
|
||||||
{
|
|
||||||
if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0)
|
|
||||||
{
|
|
||||||
listRef->insert(it,tex);
|
listRef->insert(it,tex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -652,9 +641,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head, unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
// now attach the shader to the parent surface - sort by ordinal string
|
// now attach the shader to the parent surface - sort by ordinal string
|
||||||
for (ShaderList::iterator it = surf.mShaders.begin();
|
for (ShaderList::iterator it = surf.mShaders.begin();it != surf.mShaders.end(); ++it) {
|
||||||
it != surf.mShaders.end(); ++it)
|
|
||||||
{
|
|
||||||
if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
|
if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
|
||||||
surf.mShaders.insert(it,shader);
|
surf.mShaders.insert(it,shader);
|
||||||
return;
|
return;
|
||||||
|
@ -676,26 +663,23 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||||
// check whether this surface was derived from any other surface
|
// check whether this surface was derived from any other surface
|
||||||
std::string derived;
|
std::string derived;
|
||||||
GetS0(derived,(unsigned int)(end - mFileBuffer));
|
GetS0(derived,(unsigned int)(end - mFileBuffer));
|
||||||
if (derived.length())
|
if (derived.length()) {
|
||||||
{
|
|
||||||
|
|
||||||
// yes, find this surface
|
// yes, find this surface
|
||||||
for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1;
|
for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
if ((*it).mName == derived) {
|
if ((*it).mName == derived) {
|
||||||
// we have it ...
|
// we have it ...
|
||||||
surf = *it;
|
surf = *it;
|
||||||
derived.clear();
|
derived.clear();break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!derived.size())
|
if (derived.size())
|
||||||
DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
|
DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (mFileBuffer + 6 >= end)break;
|
if (mFileBuffer + 6 >= end)
|
||||||
|
break;
|
||||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||||
|
|
||||||
if (mFileBuffer + head->length > end)
|
if (mFileBuffer + head->length > end)
|
||||||
|
@ -738,31 +722,6 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||||
surf.mTransparency = GetF4();
|
surf.mTransparency = GetF4();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// transparency mode
|
|
||||||
case AI_LWO_ALPH:
|
|
||||||
{
|
|
||||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ALPH,6);
|
|
||||||
uint16_t mode = GetU2();
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
// The surface has no effect on the alpha channel when rendered
|
|
||||||
case 0:
|
|
||||||
surf.mTransparency = 10e10f;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// The alpha channel will be written with the constant value
|
|
||||||
// following the mode in the subchunk.
|
|
||||||
case 1:
|
|
||||||
surf.mTransparency = GetF4();
|
|
||||||
break;
|
|
||||||
|
|
||||||
// The alpha value comes from the shadow density
|
|
||||||
case 3:
|
|
||||||
DefaultLogger::get()->error("LWO2: Unsupported alpha mode: shadow_density");
|
|
||||||
surf.mTransparency = 10e10f;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// additive transparency
|
// additive transparency
|
||||||
case AI_LWO_ADTR:
|
case AI_LWO_ADTR:
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -129,6 +129,7 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
||||||
double fCur = (double)timeGetTime();
|
double fCur = (double)timeGetTime();
|
||||||
|
|
||||||
aiSetImportPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
|
aiSetImportPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
|
||||||
|
//aiSetImportPropertyInteger(AI_CONFIG_PP_FD_REMOVE,1);
|
||||||
//aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
|
//aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
|
||||||
|
|
||||||
// Call ASSIMPs C-API to load the file
|
// Call ASSIMPs C-API to load the file
|
||||||
|
|
Loading…
Reference in New Issue