ASE and 3DS cleanup - face ordering improved.
Further work on target camera animation support in both loaders. Some general animation problems in both formats remaining, too. Added GenUVCoords and TransformUV-steps (see ML). The latter has been fully implemented, test file are there. GenUVCoords is a dummy for the moment. Boost workaround for shared_array. Further work on the documentation. Updated material system (see ML). Bug fixing in the AC loader, lights are now supported, too. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@243 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
130f0f39f7
commit
32342857d8
|
@ -46,7 +46,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// internal headers
|
||||
#include "3DSLoader.h"
|
||||
#include "TextureTransform.h"
|
||||
#include "TargetAnimation.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
@ -159,41 +158,60 @@ void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
|
|||
// Generate out unique verbose format representation
|
||||
void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh)
|
||||
{
|
||||
unsigned int iBase = 0;
|
||||
|
||||
// Allocate output storage
|
||||
std::vector<aiVector3D> vNew (sMesh.mFaces.size() * 3);
|
||||
std::vector<aiVector2D> vNew2;
|
||||
if (sMesh.mTexCoords.size())vNew2.resize(sMesh.mFaces.size() * 3);
|
||||
|
||||
for (unsigned int i = 0; i < sMesh.mFaces.size();++i)
|
||||
{
|
||||
uint32_t iTemp1,iTemp2;
|
||||
|
||||
// positions
|
||||
vNew[iBase] = sMesh.mPositions[sMesh.mFaces[i].mIndices[2]];
|
||||
iTemp1 = iBase++;
|
||||
vNew[iBase] = sMesh.mPositions[sMesh.mFaces[i].mIndices[1]];
|
||||
iTemp2 = iBase++;
|
||||
vNew[iBase] = sMesh.mPositions[sMesh.mFaces[i].mIndices[0]];
|
||||
|
||||
// texture coordinates
|
||||
std::vector<aiVector3D> vNew2;
|
||||
if (sMesh.mTexCoords.size())
|
||||
{
|
||||
vNew2[iTemp1] = sMesh.mTexCoords[sMesh.mFaces[i].mIndices[2]];
|
||||
vNew2[iTemp2] = sMesh.mTexCoords[sMesh.mFaces[i].mIndices[1]];
|
||||
vNew2[iBase] = sMesh.mTexCoords[sMesh.mFaces[i].mIndices[0]];
|
||||
}
|
||||
vNew2.resize(sMesh.mFaces.size() * 3);
|
||||
|
||||
sMesh.mFaces[i].mIndices[2] = iBase++;
|
||||
sMesh.mFaces[i].mIndices[0] = iTemp1;
|
||||
sMesh.mFaces[i].mIndices[1] = iTemp2;
|
||||
for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size();++i)
|
||||
{
|
||||
D3DS::Face& face = sMesh.mFaces[i];
|
||||
|
||||
// Positions
|
||||
for (unsigned int a = 0; a < 3;++a,++base)
|
||||
{
|
||||
vNew[base] = sMesh.mPositions[face.mIndices[a]];
|
||||
if (sMesh.mTexCoords.size())
|
||||
vNew2[base] = sMesh.mTexCoords[face.mIndices[a]];
|
||||
|
||||
face.mIndices[a] = base;
|
||||
}
|
||||
}
|
||||
sMesh.mPositions = vNew;
|
||||
sMesh.mTexCoords = vNew2;
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CopyTexture(MaterialHelper& mat, D3DS::Texture& texture, aiTextureType type)
|
||||
{
|
||||
// Setup the texture name
|
||||
aiString tex;
|
||||
tex.Set( texture.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
|
||||
|
||||
// Setup the texture blend factor
|
||||
if (is_not_qnan(texture.mTextureBlend))
|
||||
mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||
|
||||
// Setup the texture mapping mode
|
||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
|
||||
|
||||
// Mirroring - double the scaling values
|
||||
if (texture.mMapMode == aiTextureMapMode_Mirror)
|
||||
{
|
||||
texture.mScaleU *= 2.f;
|
||||
texture.mScaleV *= 2.f;
|
||||
texture.mOffsetU /= 2.f;
|
||||
texture.mOffsetV /= 2.f;
|
||||
}
|
||||
|
||||
// Setup texture UV transformations
|
||||
mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a 3DS material to an aiMaterial
|
||||
void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
||||
|
@ -207,12 +225,11 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
tex.Set( mBackgroundImage);
|
||||
mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
|
||||
|
||||
// be sure this is only done for the first material
|
||||
// Be sure this is only done for the first material
|
||||
mBackgroundImage = std::string("");
|
||||
}
|
||||
|
||||
// At first add the base ambient color of the
|
||||
// scene to the material
|
||||
// At first add the base ambient color of the scene to the material
|
||||
oldMat.mAmbient.r += mClrAmbient.r;
|
||||
oldMat.mAmbient.g += mClrAmbient.g;
|
||||
oldMat.mAmbient.b += mClrAmbient.b;
|
||||
|
@ -221,13 +238,13 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
name.Set( oldMat.mName);
|
||||
mat.AddProperty( &name, AI_MATKEY_NAME);
|
||||
|
||||
// material colors
|
||||
// Material colors
|
||||
mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||
mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
// phong shininess and shininess strength
|
||||
// Phong shininess and shininess strength
|
||||
if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
|
||||
D3DS::Discreet3DS::Metal == oldMat.mShading)
|
||||
{
|
||||
|
@ -242,20 +259,20 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
}
|
||||
}
|
||||
|
||||
// opacity
|
||||
// Opacity
|
||||
mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
|
||||
|
||||
// bump height scaling
|
||||
// Bump height scaling
|
||||
mat.AddProperty<float>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
|
||||
|
||||
// two sided rendering?
|
||||
// Two sided rendering?
|
||||
if (oldMat.mTwoSided)
|
||||
{
|
||||
int i = 1;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
|
||||
}
|
||||
|
||||
// shading mode
|
||||
// Shading mode
|
||||
aiShadingMode eShading = aiShadingMode_NoShading;
|
||||
switch (oldMat.mShading)
|
||||
{
|
||||
|
@ -263,8 +280,14 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
eShading = aiShadingMode_Flat; break;
|
||||
|
||||
// I don't know what "Wire" shading should be,
|
||||
// assume it is simple lambertian diffuse (L dot N) shading
|
||||
// assume it is simple lambertian diffuse shading
|
||||
case D3DS::Discreet3DS::Wire:
|
||||
{
|
||||
// Set the wireframe flag
|
||||
unsigned int iWire = 1;
|
||||
mat.AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
|
||||
}
|
||||
|
||||
case D3DS::Discreet3DS::Gouraud:
|
||||
eShading = aiShadingMode_Gouraud; break;
|
||||
|
||||
|
@ -283,112 +306,29 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
}
|
||||
mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
if (D3DS::Discreet3DS::Wire == oldMat.mShading)
|
||||
{
|
||||
// set the wireframe flag
|
||||
unsigned int iWire = 1;
|
||||
mat.AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
|
||||
}
|
||||
|
||||
// texture, if there is one
|
||||
// DIFFUSE texture
|
||||
if( oldMat.sTexDiffuse.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexDiffuse.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
CopyTexture(mat,oldMat.sTexDiffuse, aiTextureType_DIFFUSE);
|
||||
|
||||
if (is_not_qnan(oldMat.sTexDiffuse.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexDiffuse.mTextureBlend, 1, AI_MATKEY_TEXBLEND_DIFFUSE(0));
|
||||
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexDiffuse.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexSpecular.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
|
||||
}
|
||||
}
|
||||
// SPECULAR texture
|
||||
if( oldMat.sTexSpecular.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexSpecular.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(0));
|
||||
CopyTexture(mat,oldMat.sTexSpecular, aiTextureType_SPECULAR);
|
||||
|
||||
if (is_not_qnan(oldMat.sTexSpecular.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexSpecular.mTextureBlend, 1, AI_MATKEY_TEXBLEND_SPECULAR(0));
|
||||
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexSpecular.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexSpecular.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_SPECULAR(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_SPECULAR(0));
|
||||
}
|
||||
}
|
||||
// OPACITY texture
|
||||
if( oldMat.sTexOpacity.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexOpacity.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_OPACITY(0));
|
||||
CopyTexture(mat,oldMat.sTexOpacity, aiTextureType_OPACITY);
|
||||
|
||||
if (is_not_qnan(oldMat.sTexOpacity.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexOpacity.mTextureBlend, 1,AI_MATKEY_TEXBLEND_OPACITY(0));
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexOpacity.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexOpacity.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_OPACITY(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_OPACITY(0));
|
||||
}
|
||||
}
|
||||
// EMISSIVE texture
|
||||
if( oldMat.sTexEmissive.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexEmissive.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(0));
|
||||
CopyTexture(mat,oldMat.sTexEmissive, aiTextureType_EMISSIVE);
|
||||
|
||||
if (is_not_qnan(oldMat.sTexEmissive.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexEmissive.mTextureBlend, 1, AI_MATKEY_TEXBLEND_EMISSIVE(0));
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexEmissive.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexEmissive.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_EMISSIVE(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_EMISSIVE(0));
|
||||
}
|
||||
}
|
||||
// BUMP texturee
|
||||
// BUMP texture
|
||||
if( oldMat.sTexBump.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexBump.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(0));
|
||||
CopyTexture(mat,oldMat.sTexBump, aiTextureType_HEIGHT);
|
||||
|
||||
if (is_not_qnan(oldMat.sTexBump.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexBump.mTextureBlend, 1, AI_MATKEY_TEXBLEND_HEIGHT(0));
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexBump.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexBump.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_HEIGHT(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_HEIGHT(0));
|
||||
}
|
||||
}
|
||||
// SHININESS texture
|
||||
if( oldMat.sTexShininess.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( oldMat.sTexShininess.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE_SHININESS(0));
|
||||
|
||||
if (is_not_qnan(oldMat.sTexShininess.mTextureBlend))
|
||||
mat.AddProperty<float>( &oldMat.sTexShininess.mTextureBlend, 1, AI_MATKEY_TEXBLEND_SHININESS(0));
|
||||
if (aiTextureMapMode_Clamp != oldMat.sTexShininess.mMapMode)
|
||||
{
|
||||
int i = (int)oldMat.sTexShininess.mMapMode;
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_U_SHININESS(0));
|
||||
mat.AddProperty<int>(&i,1,AI_MATKEY_MAPPINGMODE_V_SHININESS(0));
|
||||
}
|
||||
}
|
||||
CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS);
|
||||
|
||||
// Store the name of the material itself, too
|
||||
if( oldMat.mName.length())
|
||||
|
@ -425,74 +365,51 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
|
|||
// now generate submeshes
|
||||
for (unsigned int p = 0; p < mScene->mMaterials.size();++p)
|
||||
{
|
||||
if (aiSplit[p].size() != 0)
|
||||
if (aiSplit[p].size())
|
||||
{
|
||||
aiMesh* p_pcOut = new aiMesh();
|
||||
p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||
aiMesh* meshOut = new aiMesh();
|
||||
meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||
|
||||
// be sure to setup the correct material index
|
||||
p_pcOut->mMaterialIndex = p;
|
||||
meshOut->mMaterialIndex = p;
|
||||
|
||||
// use the color data as temporary storage
|
||||
p_pcOut->mColors[0] = (aiColor4D*)(&*i);
|
||||
avOutMeshes.push_back(p_pcOut);
|
||||
meshOut->mColors[0] = (aiColor4D*)(&*i);
|
||||
avOutMeshes.push_back(meshOut);
|
||||
|
||||
// convert vertices
|
||||
p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
|
||||
p_pcOut->mNumVertices = p_pcOut->mNumFaces*3;
|
||||
meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
|
||||
meshOut->mNumVertices = meshOut->mNumFaces*3;
|
||||
|
||||
// allocate enough storage for faces
|
||||
p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
|
||||
iFaceCnt += p_pcOut->mNumFaces;
|
||||
meshOut->mFaces = new aiFace[meshOut->mNumFaces];
|
||||
iFaceCnt += meshOut->mNumFaces;
|
||||
|
||||
if (p_pcOut->mNumVertices)
|
||||
{
|
||||
p_pcOut->mVertices = new aiVector3D[p_pcOut->mNumVertices];
|
||||
p_pcOut->mNormals = new aiVector3D[p_pcOut->mNumVertices];
|
||||
unsigned int iBase = 0;
|
||||
|
||||
for (unsigned int q = 0; q < aiSplit[p].size();++q)
|
||||
{
|
||||
unsigned int iIndex = aiSplit[p][q];
|
||||
|
||||
p_pcOut->mFaces[q].mIndices = new unsigned int[3];
|
||||
p_pcOut->mFaces[q].mNumIndices = 3;
|
||||
|
||||
p_pcOut->mFaces[q].mIndices[2] = iBase;
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[0]];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[0]];
|
||||
|
||||
p_pcOut->mFaces[q].mIndices[1] = iBase;
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[1]];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[1]];
|
||||
|
||||
p_pcOut->mFaces[q].mIndices[0] = iBase;
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].mIndices[2]];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].mIndices[2]];
|
||||
}
|
||||
}
|
||||
// convert texture coordinates
|
||||
meshOut->mVertices = new aiVector3D[meshOut->mNumVertices];
|
||||
meshOut->mNormals = new aiVector3D[meshOut->mNumVertices];
|
||||
if ((*i).mTexCoords.size())
|
||||
{
|
||||
p_pcOut->mTextureCoords[0] = new aiVector3D[p_pcOut->mNumVertices];
|
||||
|
||||
unsigned int iBase = 0;
|
||||
for (unsigned int q = 0; q < aiSplit[p].size();++q)
|
||||
{
|
||||
unsigned int iIndex2 = aiSplit[p][q];
|
||||
|
||||
aiVector2D* pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[0]];
|
||||
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
|
||||
|
||||
pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[1]];
|
||||
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
|
||||
|
||||
pc = &(*i).mTexCoords[(*i).mFaces[iIndex2].mIndices[2]];
|
||||
p_pcOut->mTextureCoords[0][iBase++] = aiVector3D(pc->x,pc->y,0.0f);
|
||||
meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices];
|
||||
}
|
||||
for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
|
||||
{
|
||||
register unsigned int index = aiSplit[p][q];
|
||||
aiFace& face = meshOut->mFaces[q];
|
||||
|
||||
face.mIndices = new unsigned int[3];
|
||||
face.mNumIndices = 3;
|
||||
|
||||
for (unsigned int a = 0; a < 3;++a,++base)
|
||||
{
|
||||
unsigned int idx = (*i).mFaces[index].mIndices[a];
|
||||
meshOut->mVertices[base] = (*i).mPositions[idx];
|
||||
meshOut->mNormals [base] = (*i).mNormals[idx];
|
||||
|
||||
if ((*i).mTexCoords.size())
|
||||
meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx];
|
||||
|
||||
face.mIndices[a] = base;
|
||||
}
|
||||
// apply texture coordinate scalings
|
||||
TextureTransform::BakeScaleNOffset ( p_pcOut, &mScene->mMaterials[
|
||||
p_pcOut->mMaterialIndex] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,20 +425,12 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
|
|||
// We should have at least one face here
|
||||
if (!iFaceCnt)
|
||||
throw new ImportErrorException("No faces loaded. The mesh is empty");
|
||||
|
||||
// for each material in the scene we need to setup the UV source
|
||||
// set for each texture
|
||||
for (unsigned int a = 0; a < pcOut->mNumMaterials;++a)
|
||||
{
|
||||
TextureTransform::SetupMatUVSrc( pcOut->mMaterials[a], &mScene->mMaterials[a] );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Add a node to the scenegraph and setup its final transformation
|
||||
void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
||||
aiMatrix4x4& absTrafo)
|
||||
void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||
D3DS::Node* pcIn, aiMatrix4x4& absTrafo)
|
||||
{
|
||||
std::vector<unsigned int> iArray;
|
||||
iArray.reserve(3);
|
||||
|
@ -529,11 +438,12 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
aiMatrix4x4 abs;
|
||||
if (pcIn->mName == "$$$DUMMY")
|
||||
{
|
||||
// Append the "real" name of the dummy to the string
|
||||
pcIn->mName.append(pcIn->mDummyName);
|
||||
// FIX: Append the "real" name of the dummy to the string
|
||||
pcIn->mName = "Dummy." + pcIn->mDummyName;
|
||||
}
|
||||
else // if (pcIn->mName != "$$$DUMMY")
|
||||
{
|
||||
// Find all meshes with the same name as the node
|
||||
for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a)
|
||||
{
|
||||
const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0];
|
||||
|
@ -544,13 +454,10 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
}
|
||||
if (!iArray.empty())
|
||||
{
|
||||
// The matrix should be identical for all meshes with the same name.
|
||||
// It HAS to be identical for all meshes ........
|
||||
aiMatrix4x4& mTrafo = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0])->mMat;
|
||||
aiMatrix4x4 mInv = mTrafo;
|
||||
if (!configSkipPivot)
|
||||
// The matrix should be identical for all meshes with the
|
||||
// same name. It HAS to be identical for all meshes .....
|
||||
aiMatrix4x4 mInv = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0])->mMat;
|
||||
mInv.Inverse();
|
||||
|
||||
const aiVector3D& pivot = pcIn->vPivot;
|
||||
|
||||
pcOut->mNumMeshes = (unsigned int)iArray.size();
|
||||
|
@ -560,31 +467,24 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
const unsigned int iIndex = iArray[i];
|
||||
aiMesh* const mesh = pcSOut->mMeshes[iIndex];
|
||||
|
||||
// Pivot point adjustment.
|
||||
// Pivot point adjustment
|
||||
// See: http://www.zfx.info/DisplayThread.php?MID=235690#235690
|
||||
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
|
||||
aiVector3D* pvCurrent = mesh->mVertices;
|
||||
|
||||
if(pivot.x || pivot.y || pivot.z && !configSkipPivot)
|
||||
if(pivot.x || pivot.y || pivot.z)
|
||||
{
|
||||
while (pvCurrent != pvEnd)
|
||||
for (;pvCurrent != pvEnd;++pvCurrent)
|
||||
{
|
||||
*pvCurrent = mInv * (*pvCurrent);
|
||||
pvCurrent->x -= pivot.x;
|
||||
pvCurrent->y -= pivot.y;
|
||||
pvCurrent->z -= pivot.z;
|
||||
++pvCurrent;
|
||||
*pvCurrent -= pivot;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pvCurrent != pvEnd)
|
||||
{
|
||||
for (;pvCurrent != pvEnd;++pvCurrent)
|
||||
*pvCurrent = mInv * (*pvCurrent);
|
||||
++pvCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the mesh index
|
||||
pcOut->mMeshes[i] = iIndex;
|
||||
}
|
||||
|
@ -648,16 +548,21 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
}
|
||||
}
|
||||
|
||||
if (pcIn->aTargetPositionKeys.size() > 1)
|
||||
{
|
||||
//if (pcIn->aTargetPositionKeys.size() > 1)
|
||||
//{
|
||||
// DefaultLogger::get()->debug("3DS: Converting target track ...");
|
||||
|
||||
// // Camera or spot light - need to convert the separate
|
||||
// // target position channel to our representation
|
||||
// TargetAnimationHelper helper;
|
||||
|
||||
// if (pcIn->aPositionKeys.empty())
|
||||
// {
|
||||
// // We can just pass zero here ...
|
||||
// helper.SetFixedMainAnimationChannel(aiVector3D());
|
||||
// }
|
||||
// else helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
|
||||
// helper.SetTargetAnimationChannel(&pcIn->aTargetPositionKeys);
|
||||
//helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
|
||||
|
||||
// // Do the conversion
|
||||
// std::vector<aiVectorKey> distanceTrack;
|
||||
|
@ -679,12 +584,8 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
// nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
|
||||
// ::memcpy(nda->mPositionKeys,&distanceTrack[0],
|
||||
// sizeof(aiVectorKey)*nda->mNumPositionKeys);
|
||||
}
|
||||
//}
|
||||
|
||||
// Just for safety ... we *should* have at least one track here
|
||||
if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 ||
|
||||
pcIn->aScalingKeys.size() > 1)
|
||||
{
|
||||
// Allocate a new nda, increment the nda index
|
||||
aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
||||
nda->mNodeName.Set(pcIn->mName);
|
||||
|
@ -703,8 +604,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
{
|
||||
nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
|
||||
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
|
||||
::memcpy(nda->mRotationKeys,&pcIn->aRotationKeys[0],
|
||||
sizeof(aiQuatKey)*nda->mNumRotationKeys);
|
||||
|
||||
// Rotations are quaternion offsets
|
||||
aiQuaternion abs;
|
||||
for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
|
||||
{
|
||||
const aiQuatKey& q = pcIn->aRotationKeys[n];
|
||||
|
||||
abs = (n ? abs * q.mValue : q.mValue);
|
||||
nda->mRotationKeys[n].mTime = q.mTime;
|
||||
nda->mRotationKeys[n].mValue = abs.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// SCALING keys
|
||||
|
@ -716,7 +626,6 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Nod
|
|||
sizeof(aiVectorKey)*nda->mNumScalingKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the name of the node
|
||||
pcOut->mName.Set(pcIn->mName);
|
||||
|
@ -864,14 +773,6 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
|||
pcOld->mChildren[0] = NULL;
|
||||
delete pcOld;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// modify the transformation of the root node to change
|
||||
// the coordinate system of the whole scene from Max' to OpenGL
|
||||
pcOut->mRootNode->mTransformation.a3 *= -1.f;
|
||||
pcOut->mRootNode->mTransformation.b3 *= -1.f;
|
||||
pcOut->mRootNode->mTransformation.c3 *= -1.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -38,21 +38,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Defines helper data structures for the import of 3DS files.
|
||||
http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
|
||||
/** @file Defines helper data structures for the import of 3DS files */
|
||||
|
||||
#ifndef AI_3DSFILEHELPER_H_INC
|
||||
#define AI_3DSFILEHELPER_H_INC
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "../include/aiTypes.h"
|
||||
#include "../include/aiQuaternion.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiAnim.h"
|
||||
#include "../include/aiMaterial.h"
|
||||
|
||||
#include "SpatialSort.h"
|
||||
#include "SmoothingGroups.h"
|
||||
|
@ -66,12 +56,13 @@ namespace D3DS {
|
|||
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
|
||||
* and data structures.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
class Discreet3DS
|
||||
{
|
||||
public:
|
||||
private:
|
||||
inline Discreet3DS() {}
|
||||
|
||||
public:
|
||||
|
||||
//! data structure for a single chunk in a .3ds file
|
||||
struct Chunk
|
||||
{
|
||||
|
@ -79,10 +70,6 @@ public:
|
|||
uint32_t Size;
|
||||
} PACK_STRUCT;
|
||||
|
||||
//! source for this used own structures,
|
||||
//! replaced it with out standard math helpers
|
||||
typedef aiMatrix3x3 MatTransform;
|
||||
typedef aiVector3D MatTranslate;
|
||||
|
||||
//! Used for shading field in material3ds structure
|
||||
//! From AutoDesk 3ds SDK
|
||||
|
@ -301,26 +288,22 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
#include "./../include/Compiler/poppack1.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure representing a 3ds mesh face */
|
||||
struct Face : public FaceWithSmoothingGroup
|
||||
{
|
||||
//! Specifies that the face normal must be flipped.
|
||||
//! todo: do we really need this?
|
||||
bool bFlipped;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure representing a texture */
|
||||
struct Texture
|
||||
{
|
||||
//! Default constructor
|
||||
Texture()
|
||||
: mScaleU (1.0f)
|
||||
, mScaleV (1.0f)
|
||||
, mOffsetU (0.0f)
|
||||
: mOffsetU (0.0f)
|
||||
, mOffsetV (0.0f)
|
||||
, mScaleU (1.0f)
|
||||
, mScaleV (1.0f)
|
||||
, mRotation (0.0f)
|
||||
, mMapMode (aiTextureMapMode_Wrap)
|
||||
, iUVSrc (0)
|
||||
|
@ -335,10 +318,10 @@ struct Texture
|
|||
std::string mMapName;
|
||||
|
||||
//! Specifies texture coordinate offsets/scaling/rotations
|
||||
float mScaleU;
|
||||
float mScaleV;
|
||||
float mOffsetU;
|
||||
float mOffsetV;
|
||||
float mScaleU;
|
||||
float mScaleV;
|
||||
float mRotation;
|
||||
|
||||
//! Specifies the mapping mode to be used for the texture
|
||||
|
@ -348,6 +331,9 @@ struct Texture
|
|||
bool bPrivate;
|
||||
int iUVSrc;
|
||||
};
|
||||
|
||||
#include "./../include/Compiler/poppack1.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure representing a 3ds material */
|
||||
struct Material
|
||||
|
@ -414,6 +400,7 @@ struct Material
|
|||
unsigned int iBakeUVTransform;
|
||||
Texture* pcSingleTexture;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure to represent a 3ds file mesh */
|
||||
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
||||
|
@ -433,7 +420,7 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
|||
std::string mName;
|
||||
|
||||
//! Texture coordinates
|
||||
std::vector<aiVector2D> mTexCoords;
|
||||
std::vector<aiVector3D> mTexCoords;
|
||||
|
||||
//! Face materials
|
||||
std::vector<unsigned int> mFaceMaterials;
|
||||
|
|
|
@ -104,7 +104,7 @@ bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandle
|
|||
// Setup configuration properties
|
||||
void Discreet3DSImporter::SetupProperties(const Importer* pImp)
|
||||
{
|
||||
configSkipPivot = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_3DS_IGNORE_PIVOT,0) ? true : false;
|
||||
// nothing to be done for the moment
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -149,9 +149,6 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
|
|||
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(*i);
|
||||
}
|
||||
|
||||
// Apply scaling and offsets to all texture coordinates
|
||||
TextureTransform::ApplyScaleNOffset(mScene->mMaterials);
|
||||
|
||||
// Replace all occurences of the default material with a
|
||||
// valid material. Generate it if no material containing
|
||||
// DEFAULT in its name has been found in the file
|
||||
|
@ -678,6 +675,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
|||
}
|
||||
else l = & mCurrentNode->aPositionKeys;
|
||||
|
||||
l->reserve(numFrames);
|
||||
for (unsigned int i = 0; i < numFrames;++i)
|
||||
{
|
||||
unsigned int fidx = stream->GetI2();
|
||||
|
@ -724,6 +722,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
|||
|
||||
stream->IncPtr(10);
|
||||
unsigned int numFrames = stream->GetI2();
|
||||
l->reserve(numFrames);
|
||||
stream->IncPtr(2);
|
||||
|
||||
for (unsigned int i = 0; i < numFrames;++i)
|
||||
|
@ -776,6 +775,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
|||
|
||||
bool sortKeys = false;
|
||||
std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
|
||||
l->reserve(numFrames);
|
||||
|
||||
for (unsigned int i = 0; i < numFrames;++i)
|
||||
{
|
||||
|
@ -825,6 +825,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
|||
|
||||
bool sortKeys = false;
|
||||
std::vector<aiVectorKey>* l = &mCurrentNode->aScalingKeys;
|
||||
l->reserve(numFrames);
|
||||
|
||||
for (unsigned int i = 0; i < numFrames;++i)
|
||||
{
|
||||
|
@ -924,7 +925,7 @@ void Discreet3DSImporter::ParseFaceChunk()
|
|||
}
|
||||
|
||||
// Now continue and read all material indices
|
||||
cnt = stream->GetI2();
|
||||
cnt = (uint16_t)stream->GetI2();
|
||||
for (unsigned int i = 0; i < cnt;++i)
|
||||
{
|
||||
unsigned int fidx = (uint16_t)stream->GetI2();
|
||||
|
@ -957,7 +958,8 @@ void Discreet3DSImporter::ParseMeshChunk()
|
|||
case Discreet3DS::CHUNK_VERTLIST:
|
||||
{
|
||||
// This is the list of all vertices in the current mesh
|
||||
int num = stream->GetI2();
|
||||
int num = (int)(uint16_t)stream->GetI2();
|
||||
mMesh.mPositions.reserve(num);
|
||||
while (num-- > 0)
|
||||
{
|
||||
aiVector3D v;
|
||||
|
@ -985,8 +987,8 @@ void Discreet3DSImporter::ParseMeshChunk()
|
|||
mMesh.mMat.c4 = stream->GetF4();
|
||||
|
||||
// Now check whether the matrix has got a negative determinant
|
||||
// If yes, we need to flip all vertices' x axis ....
|
||||
// From lib3ds, mesh.c
|
||||
// If yes, we need to flip all vertices' Z axis ....
|
||||
// This code has been taken from lib3ds
|
||||
if (mMesh.mMat.Determinant() < 0.0f)
|
||||
{
|
||||
// Compute the inverse of the matrix
|
||||
|
@ -994,10 +996,10 @@ void Discreet3DSImporter::ParseMeshChunk()
|
|||
mInv.Inverse();
|
||||
|
||||
aiMatrix4x4 mMe = mMesh.mMat;
|
||||
mMe.a1 *= -1.0f;
|
||||
mMe.b1 *= -1.0f;
|
||||
mMe.c1 *= -1.0f;
|
||||
mMe.d1 *= -1.0f;
|
||||
mMe.c2 *= -1.0f;
|
||||
mMe.c3 *= -1.0f;
|
||||
mMe.c4 *= -1.0f;
|
||||
mInv = mInv * mMe;
|
||||
|
||||
// Now transform all vertices
|
||||
|
@ -1010,16 +1012,19 @@ void Discreet3DSImporter::ParseMeshChunk()
|
|||
c[2]= mInv[0][2]*a[0] + mInv[1][2]*a[1] + mInv[2][2]*a[2] + mInv[3][2];
|
||||
mMesh.mPositions[i] = c;
|
||||
}
|
||||
|
||||
DefaultLogger::get()->info("3DS: Flipping mesh Z-Axis");
|
||||
}}
|
||||
break;
|
||||
|
||||
case Discreet3DS::CHUNK_MAPLIST:
|
||||
{
|
||||
// This is the list of all UV coords in the current mesh
|
||||
int num = stream->GetI2();
|
||||
int num = (int)(uint16_t)stream->GetI2();
|
||||
mMesh.mTexCoords.reserve(num);
|
||||
while (num-- > 0)
|
||||
{
|
||||
aiVector2D v;
|
||||
aiVector3D v;
|
||||
v.x = stream->GetF4();
|
||||
v.y = stream->GetF4();
|
||||
mMesh.mTexCoords.push_back(v);
|
||||
|
@ -1029,7 +1034,8 @@ void Discreet3DSImporter::ParseMeshChunk()
|
|||
case Discreet3DS::CHUNK_FACELIST:
|
||||
{
|
||||
// This is the list of all faces in the current mesh
|
||||
int num = stream->GetI2();
|
||||
int num = (int)(uint16_t)stream->GetI2();
|
||||
mMesh.mFaces.reserve(num);
|
||||
while (num-- > 0)
|
||||
{
|
||||
// 3DS faces are ALWAYS triangles
|
||||
|
@ -1226,6 +1232,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
|
|||
// recursively continue processing this hierarchy level
|
||||
return ParseMaterialChunk();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||
{
|
||||
|
@ -1262,7 +1269,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
|||
if (0.0f == pcOut->mScaleU)
|
||||
{
|
||||
DefaultLogger::get()->warn("Texture coordinate scaling in the "
|
||||
"x direction is zero. Assuming this should be 1.0 ... ");
|
||||
"x direction is zero. Assuming 1");
|
||||
pcOut->mScaleU = 1.0f;
|
||||
}
|
||||
break;
|
||||
|
@ -1272,14 +1279,14 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
|||
if (0.0f == pcOut->mScaleV)
|
||||
{
|
||||
DefaultLogger::get()->warn("Texture coordinate scaling in the "
|
||||
"y direction is zero. Assuming this should be 1.0 ... ");
|
||||
"y direction is zero. Assuming 1");
|
||||
pcOut->mScaleV = 1.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
|
||||
// Texture coordinate offset in the U direction
|
||||
pcOut->mOffsetU = stream->GetF4();
|
||||
pcOut->mOffsetU = -stream->GetF4();
|
||||
break;
|
||||
|
||||
case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
|
||||
|
@ -1288,24 +1295,24 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
|||
break;
|
||||
|
||||
case Discreet3DS::CHUNK_MAT_MAP_ANG:
|
||||
// Texture coordinate rotation, CCW in radians
|
||||
pcOut->mRotation = stream->GetF4();
|
||||
// Texture coordinate rotation, CCW in DEGREES
|
||||
pcOut->mRotation = -AI_DEG_TO_RAD( stream->GetF4() );
|
||||
break;
|
||||
|
||||
case Discreet3DS::CHUNK_MAT_MAP_TILING:
|
||||
{
|
||||
uint16_t iFlags = stream->GetI2();
|
||||
|
||||
// check whether the mirror flag is set
|
||||
// Get the mapping mode (for both axes)
|
||||
if (iFlags & 0x2u)
|
||||
{
|
||||
pcOut->mMapMode = aiTextureMapMode_Mirror;
|
||||
|
||||
else if (iFlags & 0x10u)
|
||||
pcOut->mMapMode = aiTextureMapMode_Decal;
|
||||
|
||||
// wrapping in all remaining cases
|
||||
else pcOut->mMapMode = aiTextureMapMode_Wrap;
|
||||
}
|
||||
// assume that "decal" means clamping ...
|
||||
else if (iFlags & 0x10u && iFlags & 0x1u)
|
||||
{
|
||||
pcOut->mMapMode = aiTextureMapMode_Clamp;
|
||||
}}
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -238,12 +238,8 @@ protected:
|
|||
*/
|
||||
void CheckIndices(D3DS::Mesh& sMesh);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Configuration option: skip pivot chunks */
|
||||
bool configSkipPivot;
|
||||
|
||||
/** Stream to read from */
|
||||
StreamReaderLE* stream;
|
||||
|
||||
|
|
|
@ -151,11 +151,30 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
|||
if (!TokenMatch(buffer,"OBJECT",6))
|
||||
return;
|
||||
|
||||
SkipSpaces(&buffer);
|
||||
|
||||
++mNumMeshes;
|
||||
|
||||
objects.push_back(Object());
|
||||
Object& obj = objects.back();
|
||||
|
||||
aiLight* light = NULL;
|
||||
if (!ASSIMP_stricmp(buffer,"light"))
|
||||
{
|
||||
// This is a light source. Add it to the list
|
||||
mLights->push_back(light = new aiLight());
|
||||
|
||||
// Return a point light with no attenuation
|
||||
light->mType = aiLightSource_POINT;
|
||||
light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f);
|
||||
light->mAttenuationConstant = 1.f;
|
||||
|
||||
// Generate a default name for both the light source and the node
|
||||
light->mName.length = ::sprintf(light->mName.data,"ACLight_%i",mLights->size()-1);
|
||||
obj.name = std::string( light->mName.data );
|
||||
|
||||
}
|
||||
|
||||
while (GetNextLine())
|
||||
{
|
||||
if (TokenMatch(buffer,"kids",4))
|
||||
|
@ -176,6 +195,13 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
|||
{
|
||||
SkipSpaces(&buffer);
|
||||
AI_AC_GET_STRING(obj.name);
|
||||
|
||||
// If this is a light source, we'll also need to store
|
||||
// the name of the node in it.
|
||||
if (light)
|
||||
{
|
||||
light->mName.Set(obj.name);
|
||||
}
|
||||
}
|
||||
else if (TokenMatch(buffer,"texture",7))
|
||||
{
|
||||
|
@ -219,8 +245,6 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
|||
obj.vertices.push_back(aiVector3D());
|
||||
aiVector3D& v = obj.vertices.back();
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
|
||||
//std::swap(v.z,v.y);
|
||||
v.z *= -1.f;
|
||||
}
|
||||
}
|
||||
else if (TokenMatch(buffer,"numsurf",7))
|
||||
|
@ -597,7 +621,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
|||
node->mTransformation = aiMatrix4x4 ( object.rotation );
|
||||
|
||||
node->mTransformation.a4 = object.translation.x;
|
||||
node->mTransformation.b4 = object.translation.y;
|
||||
node->mTransformation.b4 = -object.translation.y;
|
||||
node->mTransformation.c4 = object.translation.z;
|
||||
|
||||
return node;
|
||||
|
@ -644,6 +668,9 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
|
|||
std::vector<Object> rootObjects;
|
||||
rootObjects.reserve(5);
|
||||
|
||||
std::vector<aiLight*> lights;
|
||||
mLights = & lights;
|
||||
|
||||
while (GetNextLine())
|
||||
{
|
||||
if (TokenMatch(buffer,"MATERIAL",8))
|
||||
|
@ -662,9 +689,9 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.rgb);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.rgb);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.rgb);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin);
|
||||
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans);
|
||||
}
|
||||
|
@ -701,6 +728,9 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
|
|||
pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials);
|
||||
if (1 != rootObjects.size())delete root;
|
||||
|
||||
if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4))
|
||||
pScene->mRootNode->mName.Set("<AC3DWorld>");
|
||||
|
||||
// build output arrays
|
||||
if (meshes.empty())
|
||||
{
|
||||
|
@ -710,10 +740,17 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
|
|||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*));
|
||||
|
||||
// build output arrays
|
||||
|
||||
pScene->mNumMaterials = (unsigned int)omaterials.size();
|
||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||
::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*));
|
||||
|
||||
pScene->mNumLights = (unsigned int)lights.size();
|
||||
if (lights.size())
|
||||
{
|
||||
pScene->mLights = new aiLight*[lights.size()];
|
||||
::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
#endif //!defined AI_BUILD_NO_AC_IMPORTER
|
||||
|
|
|
@ -236,6 +236,9 @@ private:
|
|||
// basing on this information we can find a
|
||||
// good estimate how many meshes we'll have in the final scene.
|
||||
unsigned int mNumMeshes;
|
||||
|
||||
// current list of light sources
|
||||
std::vector<aiLight*>* mLights;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
|
|
@ -48,12 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ASELoader.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "StringComparison.h"
|
||||
#include "TextureTransform.h"
|
||||
#include "SkeletonMeshBuilder.h"
|
||||
#include "TargetAnimation.h"
|
||||
|
||||
// utilities
|
||||
#include "fast_atof.h"
|
||||
#include "qnan.h"
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace Assimp::ASE;
|
||||
|
@ -156,14 +155,14 @@ void ASEImporter::InternReadFile( const std::string& pFile,
|
|||
std::vector<aiMesh*> avOutMeshes;
|
||||
avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
|
||||
for (std::vector<ASE::Mesh>::iterator
|
||||
i = mParser->m_vMeshes.begin();
|
||||
i != mParser->m_vMeshes.end();++i)
|
||||
i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i)
|
||||
{
|
||||
if ((*i).bSkip)continue;
|
||||
|
||||
// Now we need to create proper meshes from the import we
|
||||
// need to split them by materials, build valid vertex/
|
||||
// face lists ...
|
||||
// First of all - we need to build an unique mesh representation
|
||||
// that we can recompute the normal vectors easily. This is
|
||||
// also a prerequisite for the second code path in ConvertMeshes()
|
||||
// so it's difficult to optimize it away. TODO!
|
||||
BuildUniqueRepresentation(*i);
|
||||
|
||||
// Need to generate proper vertex normals if necessary
|
||||
|
@ -305,8 +304,12 @@ void ASEImporter::BuildAnimations()
|
|||
// that represent the node transformation.
|
||||
if ((*i)->mAnim.akeyPositions.size() > 1 ||
|
||||
(*i)->mAnim.akeyRotations.size() > 1 ||
|
||||
(*i)->mAnim.akeyScaling.size() > 1 ||
|
||||
(*i)->mTargetAnim.akeyPositions.size() > 1
|
||||
(*i)->mAnim.akeyScaling.size() > 1)
|
||||
{
|
||||
++iNum;
|
||||
}
|
||||
|
||||
if ((*i)->mTargetAnim.akeyPositions.size() > 1
|
||||
&& is_not_qnan( (*i)->mTargetPosition.x ))
|
||||
{
|
||||
++iNum;
|
||||
|
@ -337,6 +340,21 @@ void ASEImporter::BuildAnimations()
|
|||
aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
||||
nd->mNodeName.Set(me->mName + ".Target");
|
||||
|
||||
// If there is no input position channel we will need
|
||||
// to supply the default position from the node's
|
||||
// local transformation matrix.
|
||||
/*TargetAnimationHelper helper;
|
||||
if (me->mAnim.akeyPositions.empty())
|
||||
{
|
||||
aiMatrix4x4& mat = (*i)->mTransform;
|
||||
helper.SetFixedMainAnimationChannel(aiVector3D(
|
||||
mat.a4, mat.b4, mat.c4));
|
||||
}
|
||||
else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
|
||||
helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
|
||||
|
||||
helper.Process(&me->mTargetAnim.akeyPositions);*/
|
||||
|
||||
// Allocate the key array and fill it
|
||||
nd->mNumPositionKeys = (unsigned int) me->mTargetAnim.akeyPositions.size();
|
||||
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
|
||||
|
@ -345,7 +363,8 @@ void ASEImporter::BuildAnimations()
|
|||
nd->mNumPositionKeys * sizeof(aiVectorKey));
|
||||
}
|
||||
|
||||
if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1)
|
||||
if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 ||
|
||||
me->mAnim.akeyScaling.size() > 1)
|
||||
{
|
||||
// Begin a new node animation channel for this node
|
||||
aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
||||
|
@ -424,8 +443,6 @@ void ASEImporter::BuildCameras()
|
|||
out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
|
||||
out->mHorizontalFOV = in.mFOV;
|
||||
|
||||
// TODO: Implement proper camera target
|
||||
|
||||
out->mName.Set(in.mName);
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +497,7 @@ void ASEImporter::AddNodes(std::vector<BaseNode*>& nodes,
|
|||
aiNode* pcParent,const char* szName)
|
||||
{
|
||||
aiMatrix4x4 m;
|
||||
this->AddNodes(nodes,pcParent,szName,m);
|
||||
AddNodes(nodes,pcParent,szName,m);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -580,6 +597,12 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
|||
mParentAdjust.Inverse();
|
||||
node->mTransformation = mParentAdjust*snode->mTransform;
|
||||
|
||||
// Add sub nodes - prevent stack overflow
|
||||
if (node->mName != node->mParent->mName)
|
||||
{
|
||||
AddNodes(nodes,node,node->mName.data,snode->mTransform);
|
||||
}
|
||||
|
||||
// Further processing depends on the type of the node
|
||||
if (snode->mType == ASE::BaseNode::Mesh)
|
||||
{
|
||||
|
@ -597,40 +620,44 @@ void ASEImporter::AddNodes (std::vector<BaseNode*>& nodes,
|
|||
// target (the direction information is contained in *this*
|
||||
// node's animation track but the exact target position
|
||||
// would be lost otherwise)
|
||||
apcNodes.push_back(new aiNode());
|
||||
aiNode* node = apcNodes.back();
|
||||
|
||||
node->mName.Set ( snode->mName + ".Target" );
|
||||
node->mTransformation.a4 = snode->mTargetPosition.x;
|
||||
node->mTransformation.b4 = snode->mTargetPosition.y;
|
||||
node->mTransformation.c4 = snode->mTargetPosition.z;
|
||||
|
||||
node->mParent = pcParent;
|
||||
}
|
||||
|
||||
|
||||
// add sub nodes
|
||||
// aiMatrix4x4 mNewAbs = mat * node->mTransformation;
|
||||
|
||||
// prevent stack overflow
|
||||
if (node->mName != node->mParent->mName)
|
||||
if (!node->mNumChildren)
|
||||
{
|
||||
AddNodes(nodes,node,node->mName.data,snode->mTransform);
|
||||
node->mChildren = new aiNode*[1];
|
||||
}
|
||||
|
||||
aiNode* nd = new aiNode();
|
||||
|
||||
nd->mName.Set ( snode->mName + ".Target" );
|
||||
|
||||
nd->mTransformation.a4 = snode->mTargetPosition.x - snode->mTransform.a4;
|
||||
nd->mTransformation.b4 = snode->mTargetPosition.y - snode->mTransform.b4;
|
||||
nd->mTransformation.c4 = snode->mTargetPosition.z - snode->mTransform.c4;
|
||||
|
||||
nd->mParent = node;
|
||||
|
||||
// The .Target node is always the first child node
|
||||
for (unsigned int m = 0; m < node->mNumChildren;++m)
|
||||
node->mChildren[m+1] = node->mChildren[m];
|
||||
|
||||
node->mChildren[0] = nd;
|
||||
node->mNumChildren++;
|
||||
|
||||
// What we did is so great, it is at least worth a debug message
|
||||
DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")");
|
||||
}
|
||||
}
|
||||
|
||||
// allocate enough space for the child nodes
|
||||
// Allocate enough space for the child nodes
|
||||
// We allocate one slot more in case this is a target camera/light
|
||||
pcParent->mNumChildren = (unsigned int)apcNodes.size();
|
||||
if (pcParent->mNumChildren)
|
||||
{
|
||||
pcParent->mChildren = new aiNode*[apcNodes.size()];
|
||||
pcParent->mChildren = new aiNode*[apcNodes.size()+1 /* PLUS ONE !!! */];
|
||||
|
||||
// now build all nodes for our nice new children
|
||||
for (unsigned int p = 0; p < apcNodes.size();++p)
|
||||
{
|
||||
pcParent->mChildren[p] = apcNodes[p];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -643,7 +670,7 @@ void ASEImporter::BuildNodes()
|
|||
pcScene->mRootNode = new aiNode();
|
||||
pcScene->mRootNode->mNumMeshes = 0;
|
||||
pcScene->mRootNode->mMeshes = 0;
|
||||
pcScene->mRootNode->mName.Set("<root>");
|
||||
pcScene->mRootNode->mName.Set("<ASERoot>");
|
||||
|
||||
// Setup the coordinate system transformation
|
||||
//pcScene->mRootNode->mTransformation.c3 *= -1.f;
|
||||
|
@ -708,7 +735,7 @@ void ASEImporter::BuildNodes()
|
|||
{
|
||||
const ASE::BaseNode* src = *i;
|
||||
|
||||
// the parent is not known, so we can assume that we must add
|
||||
// The parent is not known, so we can assume that we must add
|
||||
// this node to the root node of the whole scene
|
||||
aiNode* pcNode = new aiNode();
|
||||
pcNode->mParent = pcScene->mRootNode;
|
||||
|
@ -731,16 +758,18 @@ void ASEImporter::BuildNodes()
|
|||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||
pcScene->mMeshes[i]->mColors[2] = NULL;
|
||||
|
||||
// if there is only one subnode, set it as root node
|
||||
// If there is only one subnode, set it as root node
|
||||
// FIX: The sub node may not have animations assigned
|
||||
if (1 == pcScene->mRootNode->mNumChildren && !pcScene->mNumAnimations)
|
||||
{
|
||||
aiNode* cc = pcScene->mRootNode->mChildren[0];
|
||||
aiNode* pc = pcScene->mRootNode;
|
||||
|
||||
if (!cc->mName.length)
|
||||
cc->mName = pc->mName;
|
||||
|
||||
pcScene->mRootNode = cc;
|
||||
pcScene->mRootNode->mParent = NULL;
|
||||
cc->mTransformation = pc->mTransformation * cc->mTransformation;
|
||||
cc->mParent = NULL;
|
||||
|
||||
// make sure the destructor won't delete us ...
|
||||
delete[] pc->mChildren;
|
||||
|
@ -803,17 +832,12 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
|||
for (unsigned int n = 0; n < 3;++n,++iCurrent)
|
||||
{
|
||||
mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
|
||||
//std::swap((float&)mPositions[iCurrent].z,(float&)mPositions[iCurrent].y); // DX-to-OGL
|
||||
//mPositions[iCurrent].y *= -1.f;
|
||||
|
||||
// add texture coordinates
|
||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
|
||||
{
|
||||
if (!mesh.amTexCoords[c].empty())
|
||||
{
|
||||
if (mesh.amTexCoords[c].empty())break;
|
||||
amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
|
||||
// amTexCoords[c][iCurrent].y = 1.f- amTexCoords[c][iCurrent].y; // DX-to-OGL
|
||||
}
|
||||
}
|
||||
// add vertex colors
|
||||
if (!mesh.mVertexColors.empty())
|
||||
|
@ -825,9 +849,6 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
|||
{
|
||||
mNormals[iCurrent] = mesh.mNormals[fi*3+n];
|
||||
mNormals[iCurrent].Normalize();
|
||||
|
||||
//std::swap((float&)mNormals[iCurrent].z,(float&)mNormals[iCurrent].y); // DX-to-OGL
|
||||
//mNormals[iCurrent].y *= -1.0f;
|
||||
}
|
||||
|
||||
// handle bone vertices
|
||||
|
@ -838,11 +859,9 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
|||
// will fix that again ...)
|
||||
mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]];
|
||||
}
|
||||
|
||||
(*i).mIndices[n] = iCurrent;
|
||||
}
|
||||
// we need to flip the order of the indices
|
||||
(*i).mIndices[0] = iCurrent-1;
|
||||
(*i).mIndices[1] = iCurrent-2;
|
||||
(*i).mIndices[2] = iCurrent-3;
|
||||
}
|
||||
|
||||
// replace the old arrays
|
||||
|
@ -852,20 +871,37 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
|||
|
||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
|
||||
mesh.amTexCoords[c] = amTexCoords[c];
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CopyASETexture(MaterialHelper& mat, ASE::Texture& texture, aiTextureType type)
|
||||
{
|
||||
// Setup the texture name
|
||||
aiString tex;
|
||||
tex.Set( texture.mMapName);
|
||||
mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
|
||||
|
||||
// Setup the texture blend factor
|
||||
if (is_not_qnan(texture.mTextureBlend))
|
||||
mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||
|
||||
// Setup texture UV transformations
|
||||
mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
||||
{
|
||||
// allocate the output material
|
||||
// LARGE TODO: Much code her is copied from 3DS ... join them maybe?
|
||||
|
||||
// Allocate the output material
|
||||
mat.pcInstance = new MaterialHelper();
|
||||
|
||||
// At first add the base ambient color of the
|
||||
// scene to the material
|
||||
mat.mAmbient.r += this->mParser->m_clrAmbient.r;
|
||||
mat.mAmbient.g += this->mParser->m_clrAmbient.g;
|
||||
mat.mAmbient.b += this->mParser->m_clrAmbient.b;
|
||||
mat.mAmbient.r += mParser->m_clrAmbient.r;
|
||||
mat.mAmbient.g += mParser->m_clrAmbient.g;
|
||||
mat.mAmbient.b += mParser->m_clrAmbient.b;
|
||||
|
||||
aiString name;
|
||||
name.Set( mat.mName);
|
||||
|
@ -883,7 +919,7 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
|||
mat.pcInstance->AddProperty( &mat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
|
||||
}
|
||||
// if there is no shininess, we can disable phong lighting
|
||||
// If there is no shininess, we can disable phong lighting
|
||||
else if (D3DS::Discreet3DS::Metal == mat.mShading ||
|
||||
D3DS::Discreet3DS::Phong == mat.mShading ||
|
||||
D3DS::Discreet3DS::Blinn == mat.mShading)
|
||||
|
@ -894,6 +930,12 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
|||
// opacity
|
||||
mat.pcInstance->AddProperty<float>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
|
||||
|
||||
// Two sided rendering?
|
||||
if (mat.mTwoSided)
|
||||
{
|
||||
int i = 1;
|
||||
mat.pcInstance->AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
|
||||
}
|
||||
|
||||
// shading mode
|
||||
aiShadingMode eShading = aiShadingMode_NoShading;
|
||||
|
@ -909,6 +951,11 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
|||
// I don't know what "Wire" shading should be,
|
||||
// assume it is simple lambertian diffuse (L dot N) shading
|
||||
case D3DS::Discreet3DS::Wire:
|
||||
{
|
||||
// set the wireframe flag
|
||||
unsigned int iWire = 1;
|
||||
mat.pcInstance->AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
|
||||
}
|
||||
case D3DS::Discreet3DS::Gouraud:
|
||||
eShading = aiShadingMode_Gouraud; break;
|
||||
case D3DS::Discreet3DS::Metal :
|
||||
|
@ -916,84 +963,33 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
|||
}
|
||||
mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
if (D3DS::Discreet3DS::Wire == mat.mShading)
|
||||
{
|
||||
// set the wireframe flag
|
||||
unsigned int iWire = 1;
|
||||
mat.pcInstance->AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
|
||||
}
|
||||
|
||||
// texture, if there is one
|
||||
// DIFFUSE texture
|
||||
if( mat.sTexDiffuse.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexDiffuse.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexDiffuse, aiTextureType_DIFFUSE);
|
||||
|
||||
if (is_not_qnan(mat.sTexDiffuse.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexDiffuse.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_DIFFUSE(0));
|
||||
}
|
||||
// SPECULAR texture
|
||||
if( mat.sTexSpecular.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexSpecular.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(0));
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexSpecular, aiTextureType_SPECULAR);
|
||||
|
||||
if (is_not_qnan(mat.sTexSpecular.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexSpecular.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_SPECULAR(0));
|
||||
}
|
||||
if( mat.sTexOpacity.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexOpacity.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_OPACITY(0));
|
||||
|
||||
if (is_not_qnan(mat.sTexOpacity.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexOpacity.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_OPACITY(0));
|
||||
}
|
||||
if( mat.sTexEmissive.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexEmissive.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(0));
|
||||
|
||||
if (is_not_qnan(mat.sTexEmissive.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexEmissive.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_EMISSIVE(0));
|
||||
}
|
||||
// AMBIENT texture
|
||||
if( mat.sTexAmbient.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexAmbient.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(0));
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexAmbient, aiTextureType_AMBIENT);
|
||||
|
||||
if (is_not_qnan(mat.sTexAmbient.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexAmbient.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_AMBIENT(0));
|
||||
}
|
||||
// OPACITY texture
|
||||
if( mat.sTexOpacity.mMapName.length() > 0)
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexOpacity, aiTextureType_OPACITY);
|
||||
|
||||
// EMISSIVE texture
|
||||
if( mat.sTexEmissive.mMapName.length() > 0)
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexEmissive, aiTextureType_EMISSIVE);
|
||||
|
||||
// BUMP texture
|
||||
if( mat.sTexBump.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexBump.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(0));
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexBump, aiTextureType_HEIGHT);
|
||||
|
||||
if (is_not_qnan(mat.sTexBump.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexBump.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_HEIGHT(0));
|
||||
}
|
||||
// SHININESS texture
|
||||
if( mat.sTexShininess.mMapName.length() > 0)
|
||||
{
|
||||
aiString tex;
|
||||
tex.Set( mat.sTexShininess.mMapName);
|
||||
mat.pcInstance->AddProperty( &tex, AI_MATKEY_TEXTURE_SHININESS(0));
|
||||
|
||||
if (is_not_qnan(mat.sTexShininess.mTextureBlend))
|
||||
mat.pcInstance->AddProperty<float>( &mat.sTexBump.mTextureBlend, 1,
|
||||
AI_MATKEY_TEXBLEND_SHININESS(0));
|
||||
}
|
||||
CopyASETexture(*mat.pcInstance,mat.sTexShininess, aiTextureType_SHININESS);
|
||||
|
||||
// store the name of the material itself, too
|
||||
if( mat.mName.length() > 0)
|
||||
|
@ -1086,7 +1082,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
p_pcOut->mFaces[q].mIndices = new unsigned int[3];
|
||||
p_pcOut->mFaces[q].mNumIndices = 3;
|
||||
|
||||
for (unsigned int t = 0; t < 3;++t)
|
||||
for (unsigned int t = 0; t < 3;++t, ++iBase)
|
||||
{
|
||||
const uint32_t iIndex2 = mesh.mFaces[iIndex].mIndices[t];
|
||||
|
||||
|
@ -1110,13 +1106,8 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
}
|
||||
}
|
||||
}
|
||||
++iBase;
|
||||
p_pcOut->mFaces[q].mIndices[t] = iBase;
|
||||
}
|
||||
|
||||
// Flip the face order
|
||||
p_pcOut->mFaces[q].mIndices[0] = iBase-3;
|
||||
p_pcOut->mFaces[q].mIndices[1] = iBase-2;
|
||||
p_pcOut->mFaces[q].mIndices[2] = iBase-1;
|
||||
}
|
||||
}
|
||||
// convert texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS sets supported)
|
||||
|
@ -1134,12 +1125,12 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
p_pcOut->mTextureCoords[c][iBase++] = mesh.amTexCoords[c][mesh.mFaces[iIndex].mIndices[t]];
|
||||
}
|
||||
}
|
||||
// setup the number of valid vertex components
|
||||
// Setup the number of valid vertex components
|
||||
p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
|
||||
}
|
||||
}
|
||||
|
||||
// convert vertex colors (only one set supported)
|
||||
// Convert vertex colors (only one set supported)
|
||||
if (!mesh.mVertexColors.empty())
|
||||
{
|
||||
p_pcOut->mColors[0] = new aiColor4D[p_pcOut->mNumVertices];
|
||||
|
@ -1153,6 +1144,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
}
|
||||
}
|
||||
}
|
||||
// Copy bones
|
||||
if (!mesh.mBones.empty())
|
||||
{
|
||||
p_pcOut->mNumBones = 0;
|
||||
|
@ -1211,7 +1203,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
p_pcOut->mColors[2] = (aiColor4D*) &mesh;
|
||||
avOutMeshes.push_back(p_pcOut);
|
||||
|
||||
// if the mesh hasn't faces or vertices, there are two cases
|
||||
// If the mesh hasn't faces or vertices, there are two cases
|
||||
// possible: 1. the model is invalid. 2. This is a dummy
|
||||
// helper object which we are going to remove later ...
|
||||
if (mesh.mFaces.empty() || mesh.mPositions.empty())
|
||||
|
@ -1264,10 +1256,10 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
p_pcOut->mFaces[iFace].mNumIndices = 3;
|
||||
p_pcOut->mFaces[iFace].mIndices = new unsigned int[3];
|
||||
|
||||
// copy indices (flip the face order, too)
|
||||
p_pcOut->mFaces[iFace].mIndices[0] = mesh.mFaces[iFace].mIndices[2];
|
||||
// copy indices
|
||||
p_pcOut->mFaces[iFace].mIndices[0] = mesh.mFaces[iFace].mIndices[0];
|
||||
p_pcOut->mFaces[iFace].mIndices[1] = mesh.mFaces[iFace].mIndices[1];
|
||||
p_pcOut->mFaces[iFace].mIndices[2] = mesh.mFaces[iFace].mIndices[0];
|
||||
p_pcOut->mFaces[iFace].mIndices[2] = mesh.mFaces[iFace].mIndices[2];
|
||||
}
|
||||
|
||||
// copy vertex bones
|
||||
|
@ -1328,23 +1320,20 @@ void ASEImporter::BuildMaterialIndices()
|
|||
// iterate through all materials and check whether we need them
|
||||
for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)
|
||||
{
|
||||
if (mParser->m_vMaterials[iMat].bNeed)
|
||||
{
|
||||
// convert it to the aiMaterial layout
|
||||
ASE::Material& mat = mParser->m_vMaterials[iMat];
|
||||
if (mat.bNeed)
|
||||
{
|
||||
// Convert it to the aiMaterial layout
|
||||
ConvertMaterial(mat);
|
||||
TextureTransform::ApplyScaleNOffset(mat);
|
||||
++pcScene->mNumMaterials;
|
||||
}
|
||||
for (unsigned int iSubMat = 0; iSubMat < mParser->m_vMaterials[
|
||||
iMat].avSubMaterials.size();++iSubMat)
|
||||
for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)
|
||||
{
|
||||
if (mParser->m_vMaterials[iMat].avSubMaterials[iSubMat].bNeed)
|
||||
ASE::Material& submat = mat.avSubMaterials[iSubMat];
|
||||
if (submat.bNeed)
|
||||
{
|
||||
// convert it to the aiMaterial layout
|
||||
ASE::Material& mat = mParser->m_vMaterials[iMat].avSubMaterials[iSubMat];
|
||||
ConvertMaterial(mat);
|
||||
TextureTransform::ApplyScaleNOffset(mat);
|
||||
// Convert it to the aiMaterial layout
|
||||
ConvertMaterial(submat);
|
||||
++pcScene->mNumMaterials;
|
||||
}
|
||||
}
|
||||
|
@ -1357,77 +1346,60 @@ void ASEImporter::BuildMaterialIndices()
|
|||
unsigned int iNum = 0;
|
||||
for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)
|
||||
{
|
||||
if (mParser->m_vMaterials[iMat].bNeed)
|
||||
ASE::Material& mat = mParser->m_vMaterials[iMat];
|
||||
if (mat.bNeed)
|
||||
{
|
||||
ai_assert(NULL != mParser->m_vMaterials[iMat].pcInstance);
|
||||
pcScene->mMaterials[iNum] = mParser->m_vMaterials[iMat].pcInstance;
|
||||
ai_assert(NULL != mat.pcInstance);
|
||||
pcScene->mMaterials[iNum] = mat.pcInstance;
|
||||
|
||||
// store the internal material, too
|
||||
pcIntMaterials[iNum] = &mParser->m_vMaterials[iMat];
|
||||
// Store the internal material, too
|
||||
pcIntMaterials[iNum] = &mat;
|
||||
|
||||
// iterate through all meshes and search for one which is using
|
||||
// Iterate through all meshes and search for one which is using
|
||||
// this top-level material index
|
||||
for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)
|
||||
{
|
||||
if (ASE::Face::DEFAULT_MATINDEX == pcScene->mMeshes[iMesh]->mMaterialIndex &&
|
||||
iMat == (uintptr_t)pcScene->mMeshes[iMesh]->mColors[3])
|
||||
aiMesh* mesh = pcScene->mMeshes[iMesh];
|
||||
if (ASE::Face::DEFAULT_MATINDEX == mesh->mMaterialIndex &&
|
||||
iMat == (uintptr_t)mesh->mColors[3])
|
||||
{
|
||||
pcScene->mMeshes[iMesh]->mMaterialIndex = iNum;
|
||||
pcScene->mMeshes[iMesh]->mColors[3] = NULL;
|
||||
mesh->mMaterialIndex = iNum;
|
||||
mesh->mColors[3] = NULL;
|
||||
}
|
||||
}
|
||||
iNum++;
|
||||
}
|
||||
for (unsigned int iSubMat = 0; iSubMat < mParser->m_vMaterials[iMat].avSubMaterials.size();++iSubMat)
|
||||
for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)
|
||||
{
|
||||
if (mParser->m_vMaterials[iMat].avSubMaterials[iSubMat].bNeed)
|
||||
ASE::Material& submat = mat.avSubMaterials[iSubMat];
|
||||
if (submat.bNeed)
|
||||
{
|
||||
ai_assert(NULL != mParser->m_vMaterials[iMat].avSubMaterials[iSubMat].pcInstance);
|
||||
pcScene->mMaterials[iNum] = mParser->m_vMaterials[iMat].
|
||||
avSubMaterials[iSubMat].pcInstance;
|
||||
ai_assert(NULL != submat.pcInstance);
|
||||
pcScene->mMaterials[iNum] = submat.pcInstance;
|
||||
|
||||
// store the internal material, too
|
||||
pcIntMaterials[iNum] = &mParser->m_vMaterials[iMat].avSubMaterials[iSubMat];
|
||||
// Store the internal material, too
|
||||
pcIntMaterials[iNum] = &submat;
|
||||
|
||||
// iterate through all meshes and search for one which is using
|
||||
// Iterate through all meshes and search for one which is using
|
||||
// this sub-level material index
|
||||
for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)
|
||||
{
|
||||
if (iSubMat == pcScene->mMeshes[iMesh]->mMaterialIndex &&
|
||||
iMat == (uintptr_t)pcScene->mMeshes[iMesh]->mColors[3])
|
||||
aiMesh* mesh = pcScene->mMeshes[iMesh];
|
||||
if (iSubMat == mesh->mMaterialIndex && iMat == (uintptr_t)mesh->mColors[3])
|
||||
{
|
||||
pcScene->mMeshes[iMesh]->mMaterialIndex = iNum;
|
||||
pcScene->mMeshes[iMesh]->mColors[3] = NULL;
|
||||
mesh->mMaterialIndex = iNum;
|
||||
mesh->mColors[3] = NULL;
|
||||
}
|
||||
}
|
||||
iNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// prepare for the next step
|
||||
for (unsigned int hans = 0; hans < mParser->m_vMaterials.size();++hans)
|
||||
TextureTransform::ApplyScaleNOffset(mParser->m_vMaterials[hans]);
|
||||
|
||||
// now we need to iterate through all meshes,
|
||||
// generating correct texture coordinates and material uv indices
|
||||
for (unsigned int curie = 0; curie < pcScene->mNumMeshes;++curie)
|
||||
{
|
||||
aiMesh* pcMesh = pcScene->mMeshes[curie];
|
||||
|
||||
// apply texture coordinate transformations
|
||||
TextureTransform::BakeScaleNOffset(pcMesh,pcIntMaterials[pcMesh->mMaterialIndex]);
|
||||
}
|
||||
for (unsigned int hans = 0; hans < pcScene->mNumMaterials;++hans)
|
||||
{
|
||||
// setup the correct UV indices for each material
|
||||
TextureTransform::SetupMatUVSrc(pcScene->mMaterials[hans],
|
||||
pcIntMaterials[hans]);
|
||||
}
|
||||
// Dekete our temporary array
|
||||
delete[] pcIntMaterials;
|
||||
|
||||
// finished!
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Generate normal vectors basing on smoothing groups
|
||||
bool ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
||||
|
@ -1446,6 +1418,7 @@ bool ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The array will be reused
|
||||
ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
|
||||
return false;
|
||||
|
|
|
@ -634,6 +634,12 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
|||
mat.mSpecularExponent *= 15;
|
||||
continue;
|
||||
}
|
||||
// two-sided material
|
||||
if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) )
|
||||
{
|
||||
mat.mTwoSided = true;
|
||||
continue;
|
||||
}
|
||||
// material shininess strength
|
||||
if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22))
|
||||
{
|
||||
|
@ -1387,7 +1393,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
|||
continue;
|
||||
}
|
||||
// Number of vertex colors in the mesh
|
||||
if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,14))
|
||||
if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15))
|
||||
{
|
||||
ParseLV4MeshLong(iNumCVertices);
|
||||
continue;
|
||||
|
@ -1877,44 +1883,38 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
|
|||
{
|
||||
AI_ASE_PARSER_INIT();
|
||||
|
||||
// allocate enough storage for the normals
|
||||
// Allocate enough storage for the normals
|
||||
sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
|
||||
unsigned int iIndex = 0, faceIdx = 0xffffffff;
|
||||
unsigned int index, faceIdx = 0xffffffff;
|
||||
|
||||
// ********************************************************************
|
||||
// just smooth both vertex and face normals together, so it will still
|
||||
// work if one one of the two is missing. If one of the two is invalid
|
||||
// the result will be partly corrected by this trick.
|
||||
// ********************************************************************
|
||||
// Smooth the vertex and face normals together. The result
|
||||
// will be edgy then, but otherwise everything would be soft ...
|
||||
while (true)
|
||||
{
|
||||
if ('*' == *filePtr)
|
||||
{
|
||||
++filePtr;
|
||||
if (0xffffffff != faceIdx && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17))
|
||||
if (faceIdx != 0xffffffff && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17))
|
||||
{
|
||||
aiVector3D vNormal;
|
||||
ParseLV4MeshFloatTriple(&vNormal.x,iIndex);
|
||||
ParseLV4MeshFloatTriple(&vNormal.x,index);
|
||||
|
||||
if (iIndex == sMesh.mFaces[faceIdx].mIndices[0])
|
||||
{
|
||||
iIndex = 0;
|
||||
}
|
||||
else if (iIndex == sMesh.mFaces[faceIdx].mIndices[1])
|
||||
{
|
||||
iIndex = 1;
|
||||
}
|
||||
else if (iIndex == sMesh.mFaces[faceIdx].mIndices[2])
|
||||
{
|
||||
iIndex = 2;
|
||||
}
|
||||
// Make sure we assign it to the correct face
|
||||
const ASE::Face& face = sMesh.mFaces[faceIdx];
|
||||
if (index == face.mIndices[0])
|
||||
index = 0;
|
||||
else if (index == face.mIndices[1])
|
||||
index = 1;
|
||||
else if (index == face.mIndices[2])
|
||||
index = 2;
|
||||
else
|
||||
{
|
||||
LogWarning("Normal index doesn't fit to face index");
|
||||
DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
|
||||
continue;
|
||||
}
|
||||
|
||||
// We'll renormalize later
|
||||
sMesh.mNormals[faceIdx*3 + iIndex] += vNormal;
|
||||
sMesh.mNormals[faceIdx*3+index] += vNormal;
|
||||
continue;
|
||||
}
|
||||
if (TokenMatch(filePtr,"MESH_FACENORMAL",15))
|
||||
|
@ -1922,15 +1922,14 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
|
|||
aiVector3D vNormal;
|
||||
ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
|
||||
|
||||
if (iIndex >= sMesh.mFaces.size())
|
||||
if (faceIdx >= sMesh.mFaces.size())
|
||||
{
|
||||
LogWarning("Face normal index is too large");
|
||||
faceIdx = 0xffffffff;
|
||||
DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
|
||||
continue;
|
||||
}
|
||||
|
||||
// We'll renormalize later
|
||||
sMesh.mNormals[faceIdx*3] += vNormal;
|
||||
sMesh.mNormals[faceIdx*3 +1] += vNormal;
|
||||
sMesh.mNormals[faceIdx*3 +2] += vNormal;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2037,7 +2036,7 @@ void Parser::ParseLV4MeshFace(ASE::Face& out)
|
|||
return;
|
||||
}
|
||||
|
||||
// parse smoothing groups until we don_t anymore see commas
|
||||
// Parse smoothing groups until we don't anymore see commas
|
||||
// FIX: There needn't always be a value, sad but true
|
||||
while (true)
|
||||
{
|
||||
|
|
|
@ -82,6 +82,7 @@ struct Material : public D3DS::Material
|
|||
//! Can we remove this material?
|
||||
bool bNeed;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure to represent an ASE file face */
|
||||
struct Face : public FaceWithSmoothingGroup
|
||||
|
@ -175,12 +176,6 @@ struct Animation
|
|||
, mPositionType (TRACK)
|
||||
{}
|
||||
|
||||
/** ONLY ONE OF THESE SETS IS USED
|
||||
*
|
||||
* Bezier and TCB channels are converted to a normal
|
||||
* trac later.
|
||||
*/
|
||||
|
||||
//! List of track rotation keyframes
|
||||
std::vector< aiQuatKey > akeyRotations;
|
||||
|
||||
|
|
|
@ -107,12 +107,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
||||
|
||||
# include "../include/BoostWorkaround/boost/scoped_ptr.hpp"
|
||||
# include "../include/BoostWorkaround/boost/scoped_array.hpp"
|
||||
# include "../include/BoostWorkaround/boost/format.hpp"
|
||||
# include "../include/BoostWorkaround/boost/common_factor_rt.hpp"
|
||||
|
||||
#else
|
||||
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
# include <boost/scoped_array.hpp>
|
||||
# include <boost/format.hpp>
|
||||
# include <boost/math/common_factor_rt.hpp>
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
|
|||
if (pStream.get() )
|
||||
{
|
||||
// read 200 characters from the file
|
||||
boost::scoped_ptr<char> _buffer (new char[searchBytes]);
|
||||
boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
||||
char* buffer = _buffer.get();
|
||||
|
||||
unsigned int read = (unsigned int)pStream->Read(buffer,1,searchBytes);
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file GenUVCoords step */
|
||||
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
#include "ComputeUVMappingProcess.h"
|
||||
#include "ProcessHelper.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
ComputeUVMappingProcess::ComputeUVMappingProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
ComputeUVMappingProcess::~ComputeUVMappingProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the processing step is present in the given flag field.
|
||||
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
|
||||
{
|
||||
return (pFlags & aiProcess_GenUVCoords) != 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,aiAxis axis)
|
||||
{
|
||||
DefaultLogger::get()->error("Mapping type currently not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,aiAxis axis)
|
||||
{
|
||||
DefaultLogger::get()->error("Mapping type currently not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,aiAxis axis)
|
||||
{
|
||||
DefaultLogger::get()->error("Mapping type currently not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* mesh)
|
||||
{
|
||||
DefaultLogger::get()->error("Mapping type currently not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("GenUVCoordsProcess begin");
|
||||
char buffer[1024];
|
||||
|
||||
/* Iterate through all materials and search for non-UV mapped textures
|
||||
*/
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||
{
|
||||
aiMaterial* mat = pScene->mMaterials[i];
|
||||
for (unsigned int a = 0; a < mat->mNumProperties;++a)
|
||||
{
|
||||
aiMaterialProperty* prop = mat->mProperties[a];
|
||||
if (!::strcmp( prop->mKey.data, "$tex.mapping"))
|
||||
{
|
||||
aiTextureMapping mapping = *((aiTextureMapping*)prop->mData);
|
||||
if (aiTextureMapping_UV != mapping)
|
||||
{
|
||||
if (!DefaultLogger::isNullLogger())
|
||||
{
|
||||
sprintf(buffer, "Found non-UV mapped texture (%s,%i). Mapping type: %s",
|
||||
TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
|
||||
MappingTypeToString(mapping));
|
||||
|
||||
DefaultLogger::get()->info(buffer);
|
||||
}
|
||||
|
||||
aiAxis axis;
|
||||
|
||||
// Get further properties - currently only the major axis
|
||||
for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
|
||||
{
|
||||
aiMaterialProperty* prop2 = mat->mProperties[a2];
|
||||
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
|
||||
continue;
|
||||
|
||||
if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis"))
|
||||
{
|
||||
axis = *((aiAxis*)prop2->mData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We have found a non-UV mapped texture. Now
|
||||
* we need to find all meshes using this material
|
||||
* that we can compute UV channels for them.
|
||||
*/
|
||||
for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
|
||||
{
|
||||
aiMesh* mesh = pScene->mMeshes[m];
|
||||
if (mesh->mMaterialIndex != i) continue;
|
||||
|
||||
switch (mapping)
|
||||
{
|
||||
case aiTextureMapping_SPHERE:
|
||||
ComputeSphereMapping(mesh,axis);
|
||||
break;
|
||||
case aiTextureMapping_CYLINDER:
|
||||
ComputeCylinderMapping(mesh,axis);
|
||||
break;
|
||||
case aiTextureMapping_PLANE:
|
||||
ComputePlaneMapping(mesh,axis);
|
||||
break;
|
||||
case aiTextureMapping_BOX:
|
||||
ComputeBoxMapping(mesh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug("GenUVCoordsProcess finished");
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Defines a post processing step to compute UV coordinates
|
||||
from abstract mappings, such as box or spherical*/
|
||||
#ifndef AI_COMPUTEUVMAPPING_H_INC
|
||||
#define AI_COMPUTEUVMAPPING_H_INC
|
||||
|
||||
#include "BaseProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
|
||||
class ComputeUVMappingTest;
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
|
||||
* cylindrical or boxed to proper UV coordinates for rendering.
|
||||
*/
|
||||
class ASSIMP_API ComputeUVMappingProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
friend class ::ComputeUVMappingTest; // grant the unit test full access to us
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
ComputeUVMappingProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~ComputeUVMappingProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Computes spherical UV coordinates for a mesh
|
||||
*
|
||||
* @param mesh Mesh to be processed
|
||||
* @param axis Main axis
|
||||
* @return Index of the newly generated UV channel
|
||||
*/
|
||||
unsigned int ComputeSphereMapping(aiMesh* mesh,aiAxis axis);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Computes cylindrical UV coordinates for a mesh
|
||||
*
|
||||
* @param mesh Mesh to be processed
|
||||
* @param axis Main axis
|
||||
* @return Index of the newly generated UV channel
|
||||
*/
|
||||
unsigned int ComputeCylinderMapping(aiMesh* mesh,aiAxis axis);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Computes planar UV coordinates for a mesh
|
||||
*
|
||||
* @param mesh Mesh to be processed
|
||||
* @param axis Main axis
|
||||
* @return Index of the newly generated UV channel
|
||||
*/
|
||||
unsigned int ComputePlaneMapping(aiMesh* mesh,aiAxis axis);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Computes cubic UV coordinates for a mesh
|
||||
*
|
||||
* @param mesh Mesh to be processed
|
||||
* @return Index of the newly generated UV channel
|
||||
*/
|
||||
unsigned int ComputeBoxMapping(aiMesh* mesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // AI_COMPUTEUVMAPPING_H_INC
|
|
@ -141,6 +141,10 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
|||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
ProcessMesh( pScene->mMeshes[a]);
|
||||
|
||||
// process all materials - we need to adjust UV transformations
|
||||
for( unsigned int a = 0; a < pScene->mNumMaterials; a++)
|
||||
ProcessMaterial( pScene->mMaterials[a]);
|
||||
|
||||
// transform all animation channels affecting the root node as well
|
||||
for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
|
||||
{
|
||||
|
@ -155,6 +159,25 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
|||
DefaultLogger::get()->debug("ConvertToLHProcess finished");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Converts a single material to left handed coordinates.
|
||||
void ConvertToLHProcess::ProcessMaterial (aiMaterial* mat)
|
||||
{
|
||||
for (unsigned int a = 0; a < mat->mNumProperties;++a)
|
||||
{
|
||||
aiMaterialProperty* prop = mat->mProperties[a];
|
||||
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo"))
|
||||
{
|
||||
ai_assert( prop->mDataLength >= sizeof(aiUVTransform));
|
||||
aiUVTransform* uv = (aiUVTransform*)prop->mData;
|
||||
|
||||
// just flip it, that's everything
|
||||
uv->mTranslation.y *= -1.f;
|
||||
uv->mRotation *= -1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Converts a single mesh to left handed coordinates.
|
||||
void ConvertToLHProcess::ProcessMesh( aiMesh* pMesh)
|
||||
|
|
|
@ -108,6 +108,13 @@ protected:
|
|||
*/
|
||||
void ProcessMesh( aiMesh* pMesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Converts a single material to left handed coordinates.
|
||||
* This simply means all UV offsets are inverted.
|
||||
* @param mat The material to convert.
|
||||
*/
|
||||
void ProcessMaterial (aiMaterial* mat);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Converts the given animation to LH coordinates.
|
||||
* The rotation and translation keys are transformed, the scale keys
|
||||
|
|
|
@ -108,6 +108,7 @@ void FindDegeneratesProcess::Execute( aiScene* pScene)
|
|||
// application attemps to access this data.
|
||||
face.mIndices[face.mNumIndices] = 0xdeadbeef;
|
||||
|
||||
|
||||
if(first)
|
||||
{
|
||||
++deg;
|
||||
|
|
|
@ -284,7 +284,16 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
|
|||
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
|
||||
{
|
||||
bool ret = false;
|
||||
std::vector<bool> dirtyMask;
|
||||
std::vector<bool> dirtyMask(pMesh->mNumVertices,true);
|
||||
|
||||
// Ignore elements that are not referenced by vertices.
|
||||
// (they are, for example, caused by the FindDegenerates step)
|
||||
for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
|
||||
{
|
||||
const aiFace& f = pMesh->mFaces[m];
|
||||
for (unsigned int i = 0; i < f.mNumIndices;++i)
|
||||
dirtyMask[f.mIndices[i]] = false;
|
||||
}
|
||||
|
||||
// process vertex positions
|
||||
if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask))
|
||||
|
@ -311,9 +320,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
|
|||
// -- we don't validate vertex colors, it's difficult to say whether
|
||||
// they are invalid or not.
|
||||
|
||||
// normals and tangents are undefined for point and line faces.
|
||||
// we generate a small lookup table in which we mark all
|
||||
// indices into the normals/tangents array that MAY be invalid
|
||||
// Normals and tangents are undefined for point and line faces.
|
||||
if (pMesh->mNormals || pMesh->mTangents)
|
||||
{
|
||||
if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
|
||||
|
@ -322,8 +329,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
|
|||
if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
|
||||
aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes)
|
||||
{
|
||||
// we need the lookup table
|
||||
dirtyMask.resize(pMesh->mNumVertices,false);
|
||||
// We need to update the lookup-table
|
||||
for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
|
||||
{
|
||||
const aiFace& f = pMesh->mFaces[m];
|
||||
|
@ -334,27 +340,29 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
|
|||
else if (1 == f.mNumIndices)dirtyMask[f.mIndices[0]] = true;
|
||||
}
|
||||
}
|
||||
// Normals, tangents and bitangents are undefined for
|
||||
// the whole mesh (and should not even be there)
|
||||
else return ret;
|
||||
}
|
||||
|
||||
// process mesh normals
|
||||
// Process mesh normals
|
||||
if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices,
|
||||
"normals",dirtyMask,true,false))
|
||||
ret = true;
|
||||
|
||||
// process mesh tangents
|
||||
// Process mesh tangents
|
||||
if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,
|
||||
"tangents",dirtyMask))
|
||||
{
|
||||
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
|
||||
delete[] pMesh->mTangents; pMesh->mTangents = NULL;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// process mesh bitangents
|
||||
// Process mesh bitangents
|
||||
if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,
|
||||
"bitangents",dirtyMask))
|
||||
{
|
||||
delete[] pMesh->mTangents; pMesh->mTangents = NULL;
|
||||
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// http://www.azillionmonkeys.com/qed/hash.html
|
||||
// (incremental version of the hashing function)
|
||||
// (stdint.h should have been been included here)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
|
|
|
@ -429,20 +429,6 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
|||
// lightmap settings to the last texture.
|
||||
if (cnt && matFlags & AI_IRRMESH_MAT_lightmap)
|
||||
{
|
||||
static const char* PropArray[4] =
|
||||
{
|
||||
AI_MATKEY_TEXBLEND_DIFFUSE(0),
|
||||
AI_MATKEY_TEXBLEND_DIFFUSE(1),
|
||||
AI_MATKEY_TEXBLEND_DIFFUSE(2),
|
||||
AI_MATKEY_TEXBLEND_DIFFUSE(3)
|
||||
};
|
||||
static const char* PropArray2[4] =
|
||||
{
|
||||
AI_MATKEY_TEXOP_DIFFUSE(0),
|
||||
AI_MATKEY_TEXOP_DIFFUSE(1),
|
||||
AI_MATKEY_TEXOP_DIFFUSE(2),
|
||||
AI_MATKEY_TEXOP_DIFFUSE(3)
|
||||
};
|
||||
float f = 1.f;
|
||||
|
||||
// Additive lightmap?
|
||||
|
@ -460,8 +446,8 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
|||
{
|
||||
f = 4.f;
|
||||
}
|
||||
mat->AddProperty( &f, 1, PropArray [cnt-1]);
|
||||
mat->AddProperty( &op,1, PropArray2 [cnt-1]);
|
||||
mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_DIFFUSE(cnt-1));
|
||||
mat->AddProperty( &op,1, AI_MATKEY_TEXOP_DIFFUSE(cnt-1));
|
||||
}
|
||||
|
||||
return mat;
|
||||
|
@ -600,13 +586,28 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
if (curMat)
|
||||
{
|
||||
DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please");
|
||||
delete curMat;
|
||||
delete curMat;curMat = NULL;
|
||||
}
|
||||
curMat = ParseMaterial(curMatFlags);
|
||||
}
|
||||
/* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices"))
|
||||
{
|
||||
int num = reader->getAttributeValueAsInt("vertexCount");
|
||||
|
||||
if (!num)
|
||||
{
|
||||
// This is possible ... remove the mesh from the list
|
||||
// and skip further reading
|
||||
|
||||
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices");
|
||||
|
||||
delete curMat;curMat = NULL;
|
||||
|
||||
curMesh = NULL;
|
||||
textMeaning = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
curVertices.reserve (num);
|
||||
curNormals.reserve (num);
|
||||
curColors.reserve (num);
|
||||
|
@ -648,6 +649,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
else if (ASSIMP_stricmp("standard", t))
|
||||
{
|
||||
delete curMat;
|
||||
DefaultLogger::get()->warn("IRRMESH: Unknown vertex format");
|
||||
}
|
||||
else vertexFormat = 0;
|
||||
|
@ -655,8 +657,11 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
else if (!ASSIMP_stricmp(reader->getNodeName(),"indices"))
|
||||
{
|
||||
if (curVertices.empty())
|
||||
if (curVertices.empty() && curMat)
|
||||
{
|
||||
delete curMat;
|
||||
throw new ImportErrorException("IRRMESH: indices must come after vertices");
|
||||
}
|
||||
|
||||
textMeaning = 2;
|
||||
|
||||
|
@ -665,6 +670,23 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
|
||||
// allocate storage for all faces
|
||||
curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
|
||||
if (!curMesh->mNumVertices)
|
||||
{
|
||||
// This is possible ... remove the mesh from the list
|
||||
// and skip further reading
|
||||
|
||||
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices");
|
||||
|
||||
// mesh - away
|
||||
delete curMesh; curMesh = NULL;
|
||||
|
||||
// material - away
|
||||
delete curMat;curMat = NULL;
|
||||
|
||||
textMeaning = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curMesh->mNumVertices % 3)
|
||||
{
|
||||
DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3");
|
||||
|
@ -888,7 +910,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
};
|
||||
}
|
||||
|
||||
// end of the last buffer. A material and a mesh should be there
|
||||
// End of the last buffer. A material and a mesh should be there
|
||||
if (curMat || curMesh)
|
||||
{
|
||||
if ( !curMat || !curMesh)
|
||||
|
|
|
@ -189,6 +189,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_BUILD_NO_SORTBYPTYPE_PROCESS
|
||||
# include "SortByPTypeProcess.h"
|
||||
#endif
|
||||
#ifndef AI_BUILD_NO_GENUVCOORDS_PROCESS
|
||||
# include "ComputeUVMappingProcess.h"
|
||||
#endif
|
||||
#ifndef AI_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
||||
# include "TextureTransform.h"
|
||||
#endif
|
||||
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
@ -290,7 +297,7 @@ Importer::Importer() :
|
|||
mImporter.push_back( new ColladaLoader());
|
||||
#endif
|
||||
|
||||
// add an instance of each post processing step here in the order
|
||||
// Add an instance of each post processing step here in the order
|
||||
// of sequence it is executed. steps that are added here are not validated -
|
||||
// as RegisterPPStep() does - all dependencies must be there.
|
||||
mPostProcessingSteps.reserve(25);
|
||||
|
@ -310,6 +317,17 @@ Importer::Importer() :
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef AI_BUILD_NO_GENUVCOORDS_PROCESS
|
||||
mPostProcessingSteps.push_back( new ComputeUVMappingProcess());
|
||||
#endif
|
||||
#ifndef AI_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
||||
mPostProcessingSteps.push_back( new TextureTransformStep());
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if (!defined AI_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
|
||||
mPostProcessingSteps.push_back( new RemoveRedundantMatsProcess());
|
||||
#endif
|
||||
|
@ -371,6 +389,9 @@ Importer::Importer() :
|
|||
mPostProcessingSteps.push_back( new ImproveCacheLocalityProcess());
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// allocate a SharedPostProcessInfo object and store pointers to it
|
||||
// in all post-process steps in the list.
|
||||
mPPShared = new SharedPostProcessInfo();
|
||||
|
@ -412,7 +433,9 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
|
|||
{
|
||||
ai_assert(NULL != pImp);
|
||||
|
||||
// check whether we would have two loaders for the same file extension now
|
||||
// Check whether we would have two loaders for the same file extension now
|
||||
// This is absolutely OK, but we should warn the developer of the new
|
||||
// loader that his code will propably never be called.
|
||||
|
||||
std::string st;
|
||||
pImp->GetExtensionList(st);
|
||||
|
@ -423,15 +446,14 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
|
|||
{
|
||||
if (IsExtensionSupported(std::string(sz)))
|
||||
{
|
||||
DefaultLogger::get()->error(std::string( "The file extension " ) + sz + " is already in use");
|
||||
return AI_FAILURE;
|
||||
DefaultLogger::get()->warn(std::string( "The file extension " ) + sz + " is already in use");
|
||||
}
|
||||
sz = ::strtok(NULL,";");
|
||||
}
|
||||
#endif
|
||||
|
||||
// add the loader
|
||||
this->mImporter.push_back(pImp);
|
||||
mImporter.push_back(pImp);
|
||||
DefaultLogger::get()->info("Registering custom importer: " + st);
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
@ -729,7 +751,7 @@ const std::string& Importer::GetPropertyString(const char* szName,
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
|
||||
inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
|
||||
{
|
||||
iScene += sizeof(aiNode);
|
||||
iScene += sizeof(unsigned int) * pcNode->mNumMeshes;
|
||||
|
@ -816,6 +838,10 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
|
|||
}
|
||||
in.total += in.animations;
|
||||
|
||||
// add all cameras and all lights
|
||||
in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras;
|
||||
in.total += in.lights = sizeof(aiLight) * mScene->mNumLights;
|
||||
|
||||
// add all nodes
|
||||
AddNodeWeight(in.nodes,mScene->mRootNode);
|
||||
in.total += in.nodes;
|
||||
|
@ -832,6 +858,5 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
|
|||
}
|
||||
}
|
||||
in.total += in.materials;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,11 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
// internal headers
|
||||
// Internal headers
|
||||
#include "LWOLoader.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "ByteSwap.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace LWO {
|
|||
|
||||
#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L','W','O','B')
|
||||
#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L','W','O','2')
|
||||
#define AI_LWO_FOURCC_LXOB AI_IFF_FOURCC('L','X','O','B')
|
||||
|
||||
// chunks specific to the LWOB format
|
||||
#define AI_LWO_SRFS AI_IFF_FOURCC('S','R','F','S')
|
||||
|
@ -178,6 +179,7 @@ namespace LWO {
|
|||
#define AI_LWO_AVAL AI_IFF_FOURCC('A','V','A','L')
|
||||
#define AI_LWO_GVAL AI_IFF_FOURCC('G','V','A','L')
|
||||
#define AI_LWO_BLOK AI_IFF_FOURCC('B','L','O','K')
|
||||
#define AI_LWO_VCOL AI_IFF_FOURCC('V','C','O','L')
|
||||
|
||||
/* texture layer */
|
||||
#define AI_LWO_TYPE AI_IFF_FOURCC('T','Y','P','E')
|
||||
|
@ -236,10 +238,13 @@ namespace LWO {
|
|||
|
||||
/* VMAP types */
|
||||
#define AI_LWO_TXUV AI_IFF_FOURCC('T','X','U','V')
|
||||
#define AI_LWO_RGB AI_IFF_FOURCC(' ','R','G','B')
|
||||
#define AI_LWO_RGB AI_IFF_FOURCC('R','G','B',' ')
|
||||
#define AI_LWO_RGBA AI_IFF_FOURCC('R','G','B','A')
|
||||
#define AI_LWO_WGHT AI_IFF_FOURCC('W','G','H','T')
|
||||
|
||||
// MODO extension - per-vertex normal vectors
|
||||
#define AI_LWO_MODO_NORM AI_IFF_FOURCC('N', 'O', 'R', 'M')
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Data structure for a face in a LWO file
|
||||
|
@ -318,15 +323,11 @@ struct VColorChannel : public VMapEntry
|
|||
|
||||
register unsigned int m = num*dims;
|
||||
rawData.reserve(m + (m>>2u)); // 25% as extra storage for VMADs
|
||||
rawData.resize(m,0.f);
|
||||
rawData.resize(m);
|
||||
|
||||
for (aiColor4D* p = (aiColor4D*)&rawData[0]; p < (aiColor4D*)&rawData[m-1]; ++p)
|
||||
*p = aiColor4D();
|
||||
|
||||
for (std::vector<float>::iterator it = rawData.begin(), end = rawData.end();
|
||||
it != end;++it )
|
||||
{
|
||||
for (unsigned int i = 0; i< 3;++i,++it)
|
||||
*it = 0.f;
|
||||
*it = 1.f;
|
||||
}
|
||||
abAssigned.resize(num,false);
|
||||
}
|
||||
};
|
||||
|
@ -351,6 +352,15 @@ struct WeightChannel : public VMapEntry
|
|||
{}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Represents a vertex-normals channel (MODO extension)
|
||||
*/
|
||||
struct NormalChannel : public VMapEntry
|
||||
{
|
||||
NormalChannel()
|
||||
: VMapEntry(3)
|
||||
{}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Data structure for a LWO file texture
|
||||
|
@ -515,8 +525,10 @@ struct Surface
|
|||
, mColorHighlights (0.f)
|
||||
, mMaximumSmoothAngle (0.f) // 0 == not specified, no smoothing
|
||||
, mVCMap ("")
|
||||
, mVCMapType (AI_LWO_RGBA)
|
||||
, mIOR (1.f) // vakuum
|
||||
, mBumpIntensity (1.f)
|
||||
, mWireframe (false)
|
||||
{}
|
||||
|
||||
//! Name of the surface
|
||||
|
@ -537,6 +549,7 @@ struct Surface
|
|||
|
||||
//! Vertex color map to be used to color the surface
|
||||
std::string mVCMap;
|
||||
uint32_t mVCMapType;
|
||||
|
||||
//! Names of the special shaders to be applied to the surface
|
||||
ShaderList mShaders;
|
||||
|
@ -554,6 +567,9 @@ struct Surface
|
|||
|
||||
//! Bump intensity scaling
|
||||
float mBumpIntensity;
|
||||
|
||||
//! Wireframe flag
|
||||
bool mWireframe;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -606,6 +622,9 @@ struct Layer
|
|||
/** UV channel list from the file */
|
||||
UVChannelList mUVChannels;
|
||||
|
||||
/** Normal vector channel from the file */
|
||||
NormalChannel mNormals;
|
||||
|
||||
/** Temporary face list from the file*/
|
||||
FaceList mFaces;
|
||||
|
||||
|
|
|
@ -79,11 +79,10 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
|||
if (extension.length() < 4)return false;
|
||||
if (extension[0] != '.')return false;
|
||||
|
||||
if (extension[1] != 'l' && extension[1] != 'L')return false;
|
||||
if (extension[2] != 'w' && extension[2] != 'W')return false;
|
||||
if (extension[3] != 'o' && extension[3] != 'O')return false;
|
||||
|
||||
return true;
|
||||
return ! (extension[1] != 'l' && extension[1] != 'L' ||
|
||||
extension[2] != 'w' && extension[2] != 'W' &&
|
||||
extension[2] != 'x' && extension[2] != 'X' ||
|
||||
extension[3] != 'o' && extension[3] != 'O');
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -151,11 +150,29 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
LoadLWOBFile();
|
||||
}
|
||||
|
||||
// new lightwave format
|
||||
// New lightwave format
|
||||
else if (AI_LWO_FOURCC_LWO2 == fileType)
|
||||
{
|
||||
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
|
||||
}
|
||||
// MODO file format
|
||||
else if (AI_LWO_FOURCC_LXOB == fileType)
|
||||
{
|
||||
DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
|
||||
}
|
||||
// we don't know this format
|
||||
else
|
||||
{
|
||||
char szBuff[5];
|
||||
szBuff[0] = (char)(fileType >> 24u);
|
||||
szBuff[1] = (char)(fileType >> 16u);
|
||||
szBuff[2] = (char)(fileType >> 8u);
|
||||
szBuff[3] = (char)(fileType);
|
||||
throw new ImportErrorException(std::string("Unknown LWO sub format: ") + szBuff);
|
||||
}
|
||||
|
||||
if (AI_LWO_FOURCC_LWOB != fileType)
|
||||
{
|
||||
mIsLWO2 = true;
|
||||
LoadLWO2File();
|
||||
|
||||
|
@ -172,17 +189,6 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
}
|
||||
|
||||
// we don't know this format
|
||||
else
|
||||
{
|
||||
char szBuff[5];
|
||||
szBuff[0] = (char)(fileType >> 24u);
|
||||
szBuff[1] = (char)(fileType >> 16u);
|
||||
szBuff[2] = (char)(fileType >> 8u);
|
||||
szBuff[3] = (char)(fileType);
|
||||
throw new ImportErrorException(std::string("Unknown LWO sub format: ") + szBuff);
|
||||
}
|
||||
|
||||
// now, as we have loaded all data, we can resolve cross-referenced tags and clips
|
||||
ResolveTags();
|
||||
ResolveClips();
|
||||
|
@ -249,7 +255,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
|
||||
}
|
||||
|
||||
aiVector3D* pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||
aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||
aiFace* pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||
mesh->mMaterialIndex = i;
|
||||
|
||||
|
@ -276,9 +282,13 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
|
||||
|
||||
// LightWave doesn't support more than 2 UV components
|
||||
// so we can directly setup this value
|
||||
mesh->mNumUVComponents[0] = 2;
|
||||
}
|
||||
|
||||
if (layer.mNormals.name.length())
|
||||
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
|
||||
|
||||
aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui)
|
||||
{
|
||||
|
@ -320,11 +330,24 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
pp++;
|
||||
}
|
||||
|
||||
// process normals (MODO extension)
|
||||
if (nrm)
|
||||
{
|
||||
*nrm++ = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
|
||||
}
|
||||
|
||||
// process vertex colors
|
||||
for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w)
|
||||
{
|
||||
if (0xffffffff == vVColorIndices[w])break;
|
||||
*(pvVC[w])++ = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
|
||||
*pvVC[w] = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
|
||||
|
||||
// If a RGB color map is explicitly requested delete the
|
||||
// alpha channel - it could theoretically be != 1.
|
||||
if(_mSurfaces[i].mVCMapType == AI_LWO_RGB)
|
||||
pvVC[w]->a = 1.f;
|
||||
|
||||
pvVC[w]++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -343,16 +366,19 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
pf++;
|
||||
}
|
||||
|
||||
// compute normal vectors for the mesh - we can't use our GenSmoothNormal-
|
||||
if (!mesh->mNormals)
|
||||
{
|
||||
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
|
||||
// Step here since it wouldn't handle smoothing groups correctly for LWO.
|
||||
// So we use a separate implementation.
|
||||
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
|
||||
|
||||
}
|
||||
else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
// generate nodes to render the mesh. Store the parent index
|
||||
// Generate nodes to render the mesh. Store the parent index
|
||||
// in the mParent member of the nodes
|
||||
aiNode* pcNode = new aiNode();
|
||||
apcNodes.push_back(pcNode);
|
||||
|
@ -367,7 +393,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
|||
if (apcNodes.empty() || apcMeshes.empty())
|
||||
throw new ImportErrorException("LWO: No meshes loaded");
|
||||
|
||||
// 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()];
|
||||
for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat)
|
||||
{
|
||||
|
@ -510,7 +536,6 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void LWOImporter::AddChildren(aiNode* node, uintptr_t parent, std::vector<aiNode*>& apcNodes)
|
||||
{
|
||||
parent -= 1;
|
||||
for (uintptr_t i = 0; i < (uintptr_t)apcNodes.size();++i)
|
||||
{
|
||||
if (i == parent)continue;
|
||||
|
@ -706,10 +731,15 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
|
|||
LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
|
||||
uint32_t type = GetU4();
|
||||
|
||||
if (type != AI_LWO_FACE)
|
||||
// Determine the type of the polygons
|
||||
switch (type)
|
||||
{
|
||||
DefaultLogger::get()->warn("LWO2: Only POLS.FACE chunks are supported.");
|
||||
return;
|
||||
case AI_LWO_PTCH:
|
||||
case AI_LWO_FACE:
|
||||
|
||||
break;
|
||||
default:
|
||||
DefaultLogger::get()->warn("LWO2: Unsupported polygon type (PTCH and FACE are supported)");
|
||||
}
|
||||
|
||||
// first find out how many faces and vertices we'll finally need
|
||||
|
@ -829,13 +859,9 @@ VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPol
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
|
||||
inline void CreateNewEntry(T& chan, unsigned int srcIdx)
|
||||
{
|
||||
for (typename std::vector< T >::iterator
|
||||
it = list.begin(), end = list.end();
|
||||
it != end;++it)
|
||||
{
|
||||
T& chan = *it;
|
||||
if (!chan.name.length())return;
|
||||
|
||||
chan.abAssigned[srcIdx] = true;
|
||||
chan.abAssigned.resize(chan.abAssigned.size()+1,false);
|
||||
|
@ -843,6 +869,17 @@ void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
|
|||
for (unsigned int a = 0; a < chan.dims;++a)
|
||||
chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
|
||||
{
|
||||
for (typename std::vector< T >::iterator
|
||||
it = list.begin(), end = list.end();
|
||||
it != end;++it)
|
||||
{
|
||||
CreateNewEntry( *it, srcIdx );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -911,7 +948,24 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
|
|||
}
|
||||
base = FindEntry(mCurLayer->mVColorChannels,name,perPoly);
|
||||
break;
|
||||
default: return;
|
||||
|
||||
case AI_LWO_MODO_NORM:
|
||||
|
||||
/* This is a non-standard extension chunk used by Luxology's MODO.
|
||||
* It stores per-vertex normals. This VMAP exists just once, has
|
||||
* 3 dimensions and is btw extremely beautiful.
|
||||
*/
|
||||
if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
|
||||
return;
|
||||
|
||||
DefaultLogger::get()->info("Non-standard extension: MODO VMAP.NORM.vert_normals");
|
||||
|
||||
mCurLayer->mNormals.name = name;
|
||||
base = & mCurLayer->mNormals;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
};
|
||||
base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
|
||||
|
||||
|
@ -946,20 +1000,22 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
|
|||
if (polyIdx >= numFaces)
|
||||
{
|
||||
DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range");
|
||||
mFileBuffer += base->dims*4;continue;
|
||||
mFileBuffer += base->dims*4;
|
||||
continue;
|
||||
}
|
||||
|
||||
LWO::Face& src = list[polyIdx];
|
||||
refList.resize(refList.size()+src.mNumIndices, 0xffffffff);
|
||||
|
||||
// generate new vertex positions
|
||||
// generate a new unique vertex for the corresponding index - but only
|
||||
// if we can find the index in the face
|
||||
for (unsigned int i = 0; i < src.mNumIndices;++i)
|
||||
{
|
||||
register unsigned int srcIdx = src.mIndices[i];
|
||||
if (idx == srcIdx)
|
||||
{
|
||||
if (idx != srcIdx)continue;
|
||||
|
||||
refList.resize(refList.size()+1, 0xffffffff);
|
||||
|
||||
idx = (unsigned int)pointList.size();
|
||||
}
|
||||
src.mIndices[i] = (unsigned int)pointList.size();
|
||||
|
||||
// store the index of the new vertex in the old vertex
|
||||
|
@ -971,6 +1027,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
|
|||
CreateNewEntry(mCurLayer->mVColorChannels, srcIdx );
|
||||
CreateNewEntry(mCurLayer->mUVChannels, srcIdx );
|
||||
CreateNewEntry(mCurLayer->mWeightChannels, srcIdx );
|
||||
CreateNewEntry(mCurLayer->mNormals, srcIdx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ protected:
|
|||
*/
|
||||
void GetExtensionList(std::string& append)
|
||||
{
|
||||
append.append("*.lwo");
|
||||
append.append("*.lwo;*.lxo");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -257,12 +257,10 @@ private:
|
|||
*
|
||||
* @param pcMat Output material
|
||||
* @param in Input texture list
|
||||
* @param type Type identifier of the texture list. This is the string
|
||||
* that appears in the middle of all material keys - e.g. "diffuse",
|
||||
* "shininess", "glossiness" or "specular".
|
||||
* @param type Type identifier of the texture list
|
||||
*/
|
||||
bool HandleTextures(MaterialHelper* pcMat, const TextureList& in,
|
||||
const char* type);
|
||||
aiTextureType type);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Adjust a texture path
|
||||
|
|
|
@ -59,16 +59,20 @@ T lerp(const T& one, const T& two, float val)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a lightwave mapping mode to our's
|
||||
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case LWO::Texture::REPEAT:
|
||||
return aiTextureMapMode_Wrap;
|
||||
|
||||
case LWO::Texture::MIRROR:
|
||||
return aiTextureMapMode_Mirror;
|
||||
|
||||
case LWO::Texture::RESET:
|
||||
DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
|
||||
|
||||
// fall though here
|
||||
case LWO::Texture::EDGE:
|
||||
return aiTextureMapMode_Clamp;
|
||||
|
@ -77,23 +81,67 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, const char* type)
|
||||
bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, aiTextureType type)
|
||||
{
|
||||
ai_assert(NULL != pcMat && NULL != type);
|
||||
ai_assert(NULL != pcMat);
|
||||
|
||||
unsigned int cur = 0, temp = 0;
|
||||
char buffer[512];
|
||||
aiString s;
|
||||
bool ret = false;
|
||||
|
||||
for (TextureList::const_iterator it = in.begin(), end = in.end();
|
||||
it != end;++it)
|
||||
{
|
||||
if (!(*it).enabled || !(*it).bCanUse || 0xffffffff == (*it).mRealUVIndex)continue;
|
||||
if (!(*it).enabled || !(*it).bCanUse)continue;
|
||||
ret = true;
|
||||
|
||||
// add the path to the texture
|
||||
sprintf(buffer,"$tex.file.%s[%i]",type,cur);
|
||||
// Convert lightwave's mapping modes to ours. We let them
|
||||
// as they are, the GenUVcoords step will compute UV
|
||||
// channels if they're not there.
|
||||
|
||||
aiTextureMapping mapping;
|
||||
switch ((*it).mapMode)
|
||||
{
|
||||
case LWO::Texture::Planar:
|
||||
mapping = aiTextureMapping_PLANE;
|
||||
break;
|
||||
case LWO::Texture::Cylindrical:
|
||||
mapping = aiTextureMapping_CYLINDER;
|
||||
break;
|
||||
case LWO::Texture::Spherical:
|
||||
mapping = aiTextureMapping_SPHERE;
|
||||
break;
|
||||
case LWO::Texture::Cubic:
|
||||
mapping = aiTextureMapping_BOX;
|
||||
break;
|
||||
case LWO::Texture::FrontProjection:
|
||||
DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
|
||||
mapping = aiTextureMapping_OTHER;
|
||||
break;
|
||||
case LWO::Texture::UV:
|
||||
{
|
||||
if( 0xffffffff == (*it).mRealUVIndex )
|
||||
{
|
||||
// We have no UV index for this texture, so we can't display it
|
||||
continue;
|
||||
}
|
||||
|
||||
// add the UV source index
|
||||
temp = (*it).mRealUVIndex;
|
||||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));
|
||||
|
||||
mapping = aiTextureMapping_UV;
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
if (mapping != aiTextureMapping_UV)
|
||||
{
|
||||
// Setup the main axis (the enum values map one to one)
|
||||
pcMat->AddProperty<int>((int*)&(*it).majorAxis,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
|
||||
DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
|
||||
}
|
||||
|
||||
|
||||
// The older LWOB format does not use indirect references to clips.
|
||||
// The file name of a texture is directly specified in the tex chunk.
|
||||
|
@ -133,14 +181,12 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, c
|
|||
AdjustTexturePath(ss);
|
||||
s.Set(ss);
|
||||
}
|
||||
pcMat->AddProperty(&s,buffer);
|
||||
pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));
|
||||
|
||||
// add the blend factor
|
||||
sprintf(buffer,"$tex.blend.%s[%i]",type,cur);
|
||||
pcMat->AddProperty(&(*it).mStrength,1,buffer);
|
||||
pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur));
|
||||
|
||||
// add the blend operation
|
||||
sprintf(buffer,"$tex.op.%s[%i]",type,cur);
|
||||
switch ((*it).blendType)
|
||||
{
|
||||
case LWO::Texture::Normal:
|
||||
|
@ -166,22 +212,18 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, c
|
|||
DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");
|
||||
|
||||
}
|
||||
pcMat->AddProperty<int>((int*)&temp,1,buffer);
|
||||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
|
||||
|
||||
// add the UV source index
|
||||
sprintf(buffer,"$tex.uvw.%s[%i]",type,cur);
|
||||
temp = (*it).mRealUVIndex;
|
||||
pcMat->AddProperty<int>((int*)&temp,1,buffer);
|
||||
// setup the mapping mode
|
||||
pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
|
||||
|
||||
// add the u-wrapping
|
||||
sprintf(buffer,"$tex.mapmodeu.%s[%i]",type,cur);
|
||||
temp = (unsigned int)GetMapMode((*it).wrapModeWidth);
|
||||
pcMat->AddProperty<int>((int*)&temp,1,buffer);
|
||||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));
|
||||
|
||||
// add the v-wrapping
|
||||
sprintf(buffer,"$tex.mapmodev.%s[%i]",type,cur);
|
||||
temp = (unsigned int)GetMapMode((*it).wrapModeHeight);
|
||||
pcMat->AddProperty<int>((int*)&temp,1,buffer);
|
||||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));
|
||||
|
||||
++cur;
|
||||
}
|
||||
|
@ -237,17 +279,20 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
|
|||
pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
// opacity
|
||||
if (10e10f != surf.mTransparency)
|
||||
{
|
||||
float f = 1.0f-surf.mTransparency;
|
||||
pcMat->AddProperty<float>(&f,1,AI_MATKEY_OPACITY);
|
||||
}
|
||||
|
||||
// ADD TEXTURES to the material
|
||||
// TODO: find out how we can handle COLOR textures correctly...
|
||||
bool b = HandleTextures(pcMat,surf.mColorTextures,"diffuse");
|
||||
b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,"diffuse"));
|
||||
HandleTextures(pcMat,surf.mSpecularTextures,"specular");
|
||||
HandleTextures(pcMat,surf.mGlossinessTextures,"shininess");
|
||||
HandleTextures(pcMat,surf.mBumpTextures,"height");
|
||||
HandleTextures(pcMat,surf.mOpacityTextures,"opacity");
|
||||
bool b = HandleTextures(pcMat,surf.mColorTextures,aiTextureType_DIFFUSE);
|
||||
b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,aiTextureType_DIFFUSE));
|
||||
HandleTextures(pcMat,surf.mSpecularTextures,aiTextureType_SPECULAR);
|
||||
HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS);
|
||||
HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT);
|
||||
HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY);
|
||||
|
||||
// now we need to know which shader we must use
|
||||
// iterate through the shader list of the surface and
|
||||
|
@ -255,7 +300,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
|
|||
for (ShaderList::const_iterator it = surf.mShaders.begin(), end = surf.mShaders.end();
|
||||
it != end;++it)
|
||||
{
|
||||
if (!(*it).enabled)continue;
|
||||
//if (!(*it).enabled)continue;
|
||||
if ((*it).functionName == "LW_SuperCelShader" ||
|
||||
(*it).functionName == "AH_CelShader")
|
||||
{
|
||||
|
@ -298,20 +343,11 @@ void LWOImporter::FindUVChannels(LWO::TextureList& list, LWO::Layer& layer,
|
|||
for (TextureList::iterator it = list.begin(), end = list.end();
|
||||
it != end;++it)
|
||||
{
|
||||
if (!(*it).enabled || !(*it).bCanUse || 0xffffffff != (*it).mRealUVIndex)continue;
|
||||
switch ((*it).mapMode)
|
||||
// Ignore textures with non-UV mappings for the moment.
|
||||
if (!(*it).enabled || !(*it).bCanUse || 0xffffffff != (*it).mRealUVIndex ||
|
||||
(*it).mapMode != LWO::Texture::UV)
|
||||
{
|
||||
// TODO: implement these special mappings ...
|
||||
case LWO::Texture::Spherical:
|
||||
case LWO::Texture::Cylindrical:
|
||||
case LWO::Texture::Cubic:
|
||||
case LWO::Texture::Planar:
|
||||
case LWO::Texture::FrontProjection:
|
||||
|
||||
DefaultLogger::get()->warn("LWO2: Only UV mapping is currently supported.");
|
||||
continue;
|
||||
|
||||
default: ;
|
||||
}
|
||||
for (unsigned int i = 0; i < layer.mUVChannels.size();++i)
|
||||
{
|
||||
|
@ -391,6 +427,9 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
|
|||
switch (head->type)
|
||||
{
|
||||
case AI_LWO_PROJ:
|
||||
tex.mapMode = (Texture::MappingMode)GetU2();
|
||||
break;
|
||||
case AI_LWO_WRAP:
|
||||
tex.wrapModeWidth = (Texture::Wrap)GetU2();
|
||||
tex.wrapModeHeight = (Texture::Wrap)GetU2();
|
||||
break;
|
||||
|
@ -650,10 +689,45 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
|||
// transparency
|
||||
case AI_LWO_TRAN:
|
||||
{
|
||||
if (surf.mTransparency == 10e10f)break;
|
||||
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,4);
|
||||
surf.mTransparency = GetF4();
|
||||
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;
|
||||
}
|
||||
// wireframe mode
|
||||
case AI_LWO_LINE:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LINE,2);
|
||||
if (GetU2() & 0x1)
|
||||
surf.mWireframe = true;
|
||||
break;
|
||||
}
|
||||
// glossiness
|
||||
case AI_LWO_GLOS:
|
||||
{
|
||||
|
@ -696,6 +770,18 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
|||
surf.mMaximumSmoothAngle = GetF4();
|
||||
break;
|
||||
}
|
||||
// vertex color channel to be applied to the surface
|
||||
case AI_LWO_VCOL:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,VCOL,12);
|
||||
surf.mDiffuseValue *= GetF4(); // strength
|
||||
ReadVSizedIntLWO2(mFileBuffer); // skip envelope
|
||||
surf.mVCMapType = GetU4(); // type of the channel
|
||||
|
||||
// name of the channel
|
||||
GetS0(surf.mVCMap, (unsigned int) (next - mFileBuffer ));
|
||||
break;
|
||||
}
|
||||
// surface bock entry
|
||||
case AI_LWO_BLOK:
|
||||
{
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace MDL {
|
|||
// material key that is set for dummy materials that are
|
||||
// just referencing another material
|
||||
#if (!defined AI_MDL7_REFERRER_MATERIAL)
|
||||
# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&"
|
||||
# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -43,15 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
// we are using sprintf only on fixed-size buffers, so the
|
||||
// compiler should automatically expand the template sprintf_s<>
|
||||
#if _MSC_VER >= 1400
|
||||
# define sprintf sprintf_s
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
const aiMaterialProperty** pPropOut)
|
||||
{
|
||||
ai_assert (pMat != NULL);
|
||||
|
@ -60,21 +56,24 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
|
|||
|
||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != pMat->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( pMat->mProperties[i]->mKey.data, pKey ))
|
||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
*pPropOut = pMat->mProperties[i];
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pPropOut = NULL;
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
float* pOut,
|
||||
unsigned int* pMax)
|
||||
{
|
||||
|
@ -84,9 +83,10 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
|||
|
||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != pMat->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( pMat->mProperties[i]->mKey.data, pKey ))
|
||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
// data is given in floats, simply copy it
|
||||
if( aiPTI_Float == pMat->mProperties[i]->mType ||
|
||||
|
@ -94,46 +94,40 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
|||
{
|
||||
unsigned int iWrite = pMat->mProperties[i]->mDataLength / sizeof(float);
|
||||
|
||||
if (NULL != pMax)
|
||||
iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
if (pMax)iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
::memcpy (pOut, pMat->mProperties[i]->mData, iWrite * sizeof (float));
|
||||
|
||||
memcpy (pOut, pMat->mProperties[i]->mData, iWrite * sizeof (float));
|
||||
|
||||
if (NULL != pMax)
|
||||
*pMax = iWrite;
|
||||
if (pMax)*pMax = iWrite;
|
||||
}
|
||||
// data is given in ints, convert to float
|
||||
else if( aiPTI_Integer == pMat->mProperties[i]->mType)
|
||||
{
|
||||
unsigned int iWrite = pMat->mProperties[i]->
|
||||
mDataLength / sizeof(int);
|
||||
|
||||
if (NULL != pMax)
|
||||
iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
unsigned int iWrite = pMat->mProperties[i]->mDataLength / sizeof(int);
|
||||
|
||||
if (pMax)iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
for (unsigned int a = 0; a < iWrite;++a)
|
||||
{
|
||||
pOut[a] = (float) ((int*)pMat->mProperties[i]->mData)[a];
|
||||
}
|
||||
if (NULL != pMax)
|
||||
*pMax = iWrite;
|
||||
if (pMax)*pMax = iWrite;
|
||||
}
|
||||
// it is a string ... no way to read something out of this
|
||||
else
|
||||
{
|
||||
if (NULL != pMax)
|
||||
*pMax = 0;
|
||||
if (pMax)*pMax = 0;
|
||||
return AI_FAILURE;
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
int* pOut,
|
||||
unsigned int* pMax)
|
||||
{
|
||||
|
@ -142,69 +136,66 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
|||
ai_assert (pOut != NULL);
|
||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != pMat->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( pMat->mProperties[i]->mKey.data, pKey ))
|
||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
// data is given in ints, simply copy it
|
||||
if( aiPTI_Integer == pMat->mProperties[i]->mType ||
|
||||
aiPTI_Buffer == pMat->mProperties[i]->mType)
|
||||
{
|
||||
unsigned int iWrite = pMat->mProperties[i]->
|
||||
mDataLength / sizeof(int);
|
||||
unsigned int iWrite = pMat->mProperties[i]->mDataLength / sizeof(int);
|
||||
|
||||
if (NULL != pMax)
|
||||
iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
if (pMax)iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
::memcpy (pOut, pMat->mProperties[i]->mData, iWrite * sizeof (int));
|
||||
|
||||
memcpy (pOut, pMat->mProperties[i]->mData, iWrite * sizeof (int));
|
||||
|
||||
if (NULL != pMax)
|
||||
*pMax = iWrite;
|
||||
if (pMax)*pMax = iWrite;
|
||||
}
|
||||
// data is given in floats convert to int (lossy!)
|
||||
else if( aiPTI_Float == pMat->mProperties[i]->mType)
|
||||
{
|
||||
unsigned int iWrite = pMat->mProperties[i]->
|
||||
mDataLength / sizeof(float);
|
||||
|
||||
if (NULL != pMax)
|
||||
iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
unsigned int iWrite = pMat->mProperties[i]->mDataLength / sizeof(float);
|
||||
|
||||
if (pMax)iWrite = *pMax < iWrite ? *pMax : iWrite;
|
||||
for (unsigned int a = 0; a < iWrite;++a)
|
||||
{
|
||||
pOut[a] = (int) ((float*)pMat->mProperties[i]->mData)[a];
|
||||
}
|
||||
if (NULL != pMax)
|
||||
*pMax = iWrite;
|
||||
if (pMax)*pMax = iWrite;
|
||||
}
|
||||
// it is a string ... no way to read something out of this
|
||||
else
|
||||
{
|
||||
if (NULL != pMax)
|
||||
*pMax = 0;
|
||||
if (pMax)*pMax = 0;
|
||||
return AI_FAILURE;
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialColor(const aiMaterial* pMat,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
aiColor4D* pOut)
|
||||
{
|
||||
unsigned int iMax = 4;
|
||||
aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,(float*)pOut,&iMax);
|
||||
aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax);
|
||||
|
||||
// if no alpha channel is provided set it to 1.0 by default
|
||||
if (3 == iMax)pOut->a = 1.0f;
|
||||
return eRet;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialString(const aiMaterial* pMat,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
aiString* pOut)
|
||||
{
|
||||
ai_assert (pMat != NULL);
|
||||
|
@ -213,37 +204,39 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
|
|||
|
||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i)
|
||||
{
|
||||
if (NULL != pMat->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( pMat->mProperties[i]->mKey.data, pKey ))
|
||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
if( aiPTI_String == pMat->mProperties[i]->mType)
|
||||
{
|
||||
const aiString* pcSrc = (const aiString*)pMat->mProperties[i]->mData;
|
||||
::memcpy (pOut->data, pcSrc->data, (pOut->length = pcSrc->length)+1);
|
||||
}
|
||||
// wrong type
|
||||
// Wrong type
|
||||
else return AI_FAILURE;
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MaterialHelper::MaterialHelper()
|
||||
{
|
||||
// allocate 5 entries by default
|
||||
this->mNumProperties = 0;
|
||||
this->mNumAllocated = 5;
|
||||
this->mProperties = new aiMaterialProperty*[5];
|
||||
return;
|
||||
// Allocate 5 entries by default
|
||||
mNumProperties = 0;
|
||||
mNumAllocated = 5;
|
||||
mProperties = new aiMaterialProperty*[5];
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MaterialHelper::~MaterialHelper()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void MaterialHelper::Clear()
|
||||
{
|
||||
|
@ -252,7 +245,11 @@ void MaterialHelper::Clear()
|
|||
// delete this entry
|
||||
delete mProperties[i];
|
||||
}
|
||||
mNumProperties = 0;
|
||||
|
||||
// The array remains
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
uint32_t MaterialHelper::ComputeHash()
|
||||
{
|
||||
|
@ -262,45 +259,62 @@ uint32_t MaterialHelper::ComputeHash()
|
|||
aiMaterialProperty* prop;
|
||||
|
||||
// NOTE: We need to exclude the material name from the hash
|
||||
if ((prop = this->mProperties[i]) && 0 != ::strcmp(prop->mKey.data,AI_MATKEY_NAME))
|
||||
if ((prop = this->mProperties[i]) && ::strcmp(prop->mKey.data,"$mat.name"))
|
||||
{
|
||||
hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
|
||||
hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
|
||||
|
||||
// Combine the semantic and the index with the hash
|
||||
// We print them to a string to make sure the quality
|
||||
// of the hash isn't decreased.
|
||||
char buff[32];
|
||||
unsigned int len;
|
||||
|
||||
len = itoa10(buff,prop->mSemantic);
|
||||
hash = SuperFastHash(buff,len-1,hash);
|
||||
|
||||
len = itoa10(buff,prop->mIndex);
|
||||
hash = SuperFastHash(buff,len-1,hash);
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn MaterialHelper::RemoveProperty (const char* pKey)
|
||||
aiReturn MaterialHelper::RemoveProperty (const char* pKey,unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
ai_assert(NULL != pKey);
|
||||
|
||||
for (unsigned int i = 0; i < this->mNumProperties;++i)
|
||||
for (unsigned int i = 0; i < mNumProperties;++i)
|
||||
{
|
||||
if (this->mProperties[i]) // just for safety
|
||||
aiMaterialProperty* prop = mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( this->mProperties[i]->mKey.data, pKey ))
|
||||
{
|
||||
// delete this entry
|
||||
delete this->mProperties[i];
|
||||
// Delete this entry
|
||||
delete mProperties[i];
|
||||
|
||||
// collapse the array behind --.
|
||||
--this->mNumProperties;
|
||||
for (unsigned int a = i; a < this->mNumProperties;++a)
|
||||
--mNumProperties;
|
||||
for (unsigned int a = i; a < mNumProperties;++a)
|
||||
{
|
||||
this->mProperties[a] = this->mProperties[a+1];
|
||||
mProperties[a] = mProperties[a+1];
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
||||
const unsigned int pSizeInBytes,
|
||||
unsigned int pSizeInBytes,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
aiPropertyTypeInfo pType)
|
||||
{
|
||||
ai_assert (pInput != NULL);
|
||||
|
@ -310,27 +324,30 @@ aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
|||
// first search the list whether there is already an entry
|
||||
// with this name.
|
||||
unsigned int iOutIndex = 0xFFFFFFFF;
|
||||
for (unsigned int i = 0; i < this->mNumProperties;++i)
|
||||
for (unsigned int i = 0; i < mNumProperties;++i)
|
||||
{
|
||||
if (this->mProperties[i])
|
||||
{
|
||||
if (0 == ASSIMP_stricmp( this->mProperties[i]->mKey.data, pKey ))
|
||||
aiMaterialProperty* prop = mProperties[i];
|
||||
|
||||
if (prop && !::strcmp( prop->mKey.data, pKey ) &&
|
||||
prop->mSemantic == type && prop->mIndex == index)
|
||||
{
|
||||
// delete this entry
|
||||
delete this->mProperties[i];
|
||||
iOutIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a new material property
|
||||
aiMaterialProperty* pcNew = new aiMaterialProperty();
|
||||
|
||||
// fill this
|
||||
// Fill this
|
||||
pcNew->mType = pType;
|
||||
pcNew->mSemantic = type;
|
||||
pcNew->mIndex = index;
|
||||
|
||||
pcNew->mDataLength = pSizeInBytes;
|
||||
pcNew->mData = new char[pSizeInBytes];
|
||||
memcpy (pcNew->mData,pInput,pSizeInBytes);
|
||||
::memcpy (pcNew->mData,pInput,pSizeInBytes);
|
||||
|
||||
pcNew->mKey.length = ::strlen(pKey);
|
||||
ai_assert ( MAXLEN > pcNew->mKey.length);
|
||||
|
@ -338,37 +355,41 @@ aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
|
|||
|
||||
if (0xFFFFFFFF != iOutIndex)
|
||||
{
|
||||
this->mProperties[iOutIndex] = pcNew;
|
||||
mProperties[iOutIndex] = pcNew;
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// resize the array ... allocate storage for 5 other properties
|
||||
if (this->mNumProperties == this->mNumAllocated)
|
||||
if (mNumProperties == mNumAllocated)
|
||||
{
|
||||
unsigned int iOld = this->mNumAllocated;
|
||||
this->mNumAllocated += 5;
|
||||
unsigned int iOld = mNumAllocated;
|
||||
mNumAllocated += 5;
|
||||
|
||||
aiMaterialProperty** ppTemp = new aiMaterialProperty*[this->mNumAllocated];
|
||||
aiMaterialProperty** ppTemp = new aiMaterialProperty*[mNumAllocated];
|
||||
if (NULL == ppTemp)return AI_OUTOFMEMORY;
|
||||
|
||||
::memcpy (ppTemp,this->mProperties,iOld * sizeof(void*));
|
||||
::memcpy (ppTemp,mProperties,iOld * sizeof(void*));
|
||||
|
||||
delete[] this->mProperties;
|
||||
this->mProperties = ppTemp;
|
||||
delete[] mProperties;
|
||||
mProperties = ppTemp;
|
||||
}
|
||||
// push back ...
|
||||
this->mProperties[this->mNumProperties++] = pcNew;
|
||||
mProperties[mNumProperties++] = pcNew;
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn MaterialHelper::AddProperty (const aiString* pInput,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
// fix ... don't keep the whole string buffer
|
||||
// Fix ... don't keep the whole string buffer
|
||||
return this->AddBinaryProperty(pInput,(unsigned int)pInput->length+1+
|
||||
(unsigned int)(((uint8_t*)&pInput->data - (uint8_t*)&pInput->length)),
|
||||
pKey,aiPTI_String);
|
||||
pKey,type,index, aiPTI_String);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest,
|
||||
const MaterialHelper* pcSrc)
|
||||
|
@ -400,7 +421,8 @@ void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest,
|
|||
for (unsigned int q = 0; q < iOldNum;++q)
|
||||
{
|
||||
prop = pcDest->mProperties[q];
|
||||
if (!ASSIMP_stricmp(propSrc->mKey.data,prop->mKey.data))
|
||||
if (prop && prop->mKey == propSrc->mKey &&
|
||||
prop->mSemantic == propSrc->mSemantic && prop->mIndex == propSrc->mIndex)
|
||||
{
|
||||
delete prop;
|
||||
|
||||
|
@ -411,171 +433,69 @@ void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest,
|
|||
}
|
||||
}
|
||||
|
||||
// Allocate the output property and copy the source property
|
||||
prop = pcDest->mProperties[i] = new aiMaterialProperty();
|
||||
prop->mKey = propSrc->mKey;
|
||||
prop->mDataLength = propSrc->mDataLength;
|
||||
prop->mType = propSrc->mType;
|
||||
prop->mSemantic = propSrc->mSemantic;
|
||||
prop->mIndex = propSrc->mIndex;
|
||||
|
||||
prop->mData = new char[propSrc->mDataLength];
|
||||
::memcpy(prop->mData,propSrc->mData,prop->mDataLength);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// we need this dummy because the compiler would otherwise complain about
|
||||
// empty, but controlled statements ...
|
||||
void DummyAssertFunction()
|
||||
aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
|
||||
aiTextureType type,
|
||||
unsigned int index,
|
||||
C_STRUCT aiString* path,
|
||||
aiTextureMapping* _mapping /*= NULL*/,
|
||||
unsigned int* uvindex /*= NULL*/,
|
||||
float* blend /*= NULL*/,
|
||||
aiTextureOp* op /*= NULL*/,
|
||||
aiTextureMapMode* mapmode /*= NULL*/)
|
||||
{
|
||||
ai_assert(false);
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn aiGetMaterialTexture(const aiMaterial* pcMat,
|
||||
unsigned int iIndex,
|
||||
unsigned int iTexType,
|
||||
aiString* szOut,
|
||||
unsigned int* piUVIndex,
|
||||
float* pfBlendFactor,
|
||||
aiTextureOp* peTextureOp,
|
||||
aiTextureMapMode* peMapMode)
|
||||
{
|
||||
ai_assert(NULL != pcMat);
|
||||
ai_assert(NULL != szOut);
|
||||
ai_assert(NULL != mat && NULL != path);
|
||||
|
||||
const char* szPathBase;
|
||||
const char* szUVBase;
|
||||
const char* szBlendBase;
|
||||
const char* szOpBase;
|
||||
const char* aszMapModeBase[3];
|
||||
switch (iTexType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
szPathBase = AI_MATKEY_TEXTURE_DIFFUSE_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_DIFFUSE_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_DIFFUSE_;
|
||||
szOpBase = AI_MATKEY_TEXOP_DIFFUSE_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_DIFFUSE_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_DIFFUSE_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_DIFFUSE_;
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
szPathBase = AI_MATKEY_TEXTURE_SPECULAR_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_SPECULAR_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_SPECULAR_;
|
||||
szOpBase = AI_MATKEY_TEXOP_SPECULAR_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_SPECULAR_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_SPECULAR_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_SPECULAR_;
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
szPathBase = AI_MATKEY_TEXTURE_AMBIENT_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_AMBIENT_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_AMBIENT_;
|
||||
szOpBase = AI_MATKEY_TEXOP_AMBIENT_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_AMBIENT_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_AMBIENT_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_AMBIENT_;
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
szPathBase = AI_MATKEY_TEXTURE_EMISSIVE_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_EMISSIVE_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_EMISSIVE_;
|
||||
szOpBase = AI_MATKEY_TEXOP_EMISSIVE_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_EMISSIVE_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_EMISSIVE_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_EMISSIVE_;
|
||||
break;
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
szPathBase = AI_MATKEY_TEXTURE_HEIGHT_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_HEIGHT_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_HEIGHT_;
|
||||
szOpBase = AI_MATKEY_TEXOP_HEIGHT_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_HEIGHT_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_HEIGHT_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_HEIGHT_;
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
szPathBase = AI_MATKEY_TEXTURE_NORMALS_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_NORMALS_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_NORMALS_;
|
||||
szOpBase = AI_MATKEY_TEXOP_NORMALS_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_NORMALS_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_NORMALS_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_NORMALS_;
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
szPathBase = AI_MATKEY_TEXTURE_SHININESS_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_SHININESS_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_SHININESS_;
|
||||
szOpBase = AI_MATKEY_TEXOP_SHININESS_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_SHININESS_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_SHININESS_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_SHININESS_;
|
||||
break;
|
||||
case AI_TEXTYPE_OPACITY:
|
||||
szPathBase = AI_MATKEY_TEXTURE_OPACITY_;
|
||||
szUVBase = AI_MATKEY_UVWSRC_OPACITY_;
|
||||
szBlendBase = AI_MATKEY_TEXBLEND_OPACITY_;
|
||||
szOpBase = AI_MATKEY_TEXOP_OPACITY_;
|
||||
aszMapModeBase[0] = AI_MATKEY_MAPPINGMODE_U_OPACITY_;
|
||||
aszMapModeBase[1] = AI_MATKEY_MAPPINGMODE_V_OPACITY_;
|
||||
aszMapModeBase[2] = AI_MATKEY_MAPPINGMODE_W_OPACITY_;
|
||||
break;
|
||||
default: return AI_FAILURE;
|
||||
};
|
||||
|
||||
char szKey[256];
|
||||
if (iIndex > 100)return AI_FAILURE;
|
||||
|
||||
// get the path to the texture
|
||||
if(0 >= sprintf(szKey,"%s[%i]",szPathBase,iIndex))DummyAssertFunction();
|
||||
if (AI_SUCCESS != aiGetMaterialString(pcMat,szKey,szOut))
|
||||
// Get the path to the texture
|
||||
aiString string;
|
||||
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),&string))
|
||||
{
|
||||
return AI_FAILURE;
|
||||
}
|
||||
// get the UV index of the texture
|
||||
if (piUVIndex)
|
||||
{
|
||||
int iUV;
|
||||
if(0 >= sprintf(szKey,"%s[%i]",szUVBase,iIndex))DummyAssertFunction();
|
||||
if (AI_SUCCESS != aiGetMaterialInteger(pcMat,szKey,&iUV))
|
||||
iUV = 0;
|
||||
|
||||
*piUVIndex = iUV;
|
||||
}
|
||||
// get the blend factor of the texture
|
||||
if (pfBlendFactor)
|
||||
{
|
||||
float fBlend;
|
||||
if(0 >= sprintf(szKey,"%s[%i]",szBlendBase,iIndex))DummyAssertFunction();
|
||||
if (AI_SUCCESS != aiGetMaterialFloat(pcMat,szKey,&fBlend))
|
||||
fBlend = 1.0f;
|
||||
// Determine the mapping type of the texture
|
||||
aiTextureMapping mapping = aiTextureMapping_UV;
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
|
||||
if (_mapping)*_mapping = mapping;
|
||||
|
||||
*pfBlendFactor = fBlend;
|
||||
// Get the UV index of the texture
|
||||
if (aiTextureMapping_UV == mapping && uvindex)
|
||||
{
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex);
|
||||
}
|
||||
|
||||
// get the texture operation of the texture
|
||||
if (peTextureOp)
|
||||
// Get the blend factor of the texture
|
||||
if (blend)
|
||||
{
|
||||
aiTextureOp op;
|
||||
if(0 >= sprintf(szKey,"%s[%i]",szOpBase,iIndex))DummyAssertFunction();
|
||||
if (AI_SUCCESS != aiGetMaterialInteger(pcMat,szKey,(int*)&op))
|
||||
op = aiTextureOp_Multiply;
|
||||
aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend);
|
||||
}
|
||||
|
||||
*peTextureOp = op;
|
||||
// Get the texture operation of the texture
|
||||
if (op)
|
||||
{
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op);
|
||||
}
|
||||
|
||||
// get the texture mapping modes for the texture
|
||||
if (peMapMode)
|
||||
if (mapmode)
|
||||
{
|
||||
aiTextureMapMode eMode;
|
||||
for (unsigned int q = 0; q < 3;++q)
|
||||
{
|
||||
if(0 >= sprintf(szKey,"%s[%i]",aszMapModeBase[q],iIndex))DummyAssertFunction();
|
||||
if (AI_SUCCESS != aiGetMaterialInteger(pcMat,szKey,(int*)&eMode))
|
||||
{
|
||||
eMode = aiTextureMapMode_Wrap;
|
||||
}
|
||||
peMapMode[q] = eMode;
|
||||
}
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]);
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]);
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_W(type,index),(int*)&mapmode[2]);
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -65,11 +65,15 @@ public:
|
|||
* \param pInput Pointer to input data
|
||||
* \param pSizeInBytes Size of input data
|
||||
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
|
||||
* \param type Set by the AI_MATKEY_XXX macro
|
||||
* \param index Set by the AI_MATKEY_XXX macro
|
||||
* \param pType Type information hint
|
||||
*/
|
||||
aiReturn AddBinaryProperty (const void* pInput,
|
||||
const unsigned int pSizeInBytes,
|
||||
unsigned int pSizeInBytes,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index,
|
||||
aiPropertyTypeInfo pType);
|
||||
|
||||
|
||||
|
@ -79,9 +83,13 @@ public:
|
|||
*
|
||||
* \param pInput Input string
|
||||
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
|
||||
* \param type Set by the AI_MATKEY_XXX macro
|
||||
* \param index Set by the AI_MATKEY_XXX macro
|
||||
*/
|
||||
aiReturn AddProperty (const aiString* pInput,
|
||||
const char* pKey);
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -89,20 +97,26 @@ public:
|
|||
* \param pInput Pointer to the input data
|
||||
* \param pNumValues Number of values in the array
|
||||
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
|
||||
* \param type Set by the AI_MATKEY_XXX macro
|
||||
* \param index Set by the AI_MATKEY_XXX macro
|
||||
*/
|
||||
template<class TYPE>
|
||||
aiReturn AddProperty (const TYPE* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey);
|
||||
unsigned int pNumValues,
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Remove a given key from the list
|
||||
* The function fails if the key isn't found
|
||||
*
|
||||
* \param pKey Key/Usage to be deleted
|
||||
* \param pKey Key to be deleted
|
||||
*/
|
||||
aiReturn RemoveProperty (const char* pKey);
|
||||
aiReturn RemoveProperty (const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -136,11 +150,13 @@ public:
|
|||
template<class TYPE>
|
||||
aiReturn MaterialHelper::AddProperty (const TYPE* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
return this->AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(TYPE),
|
||||
pKey,aiPTI_Buffer);
|
||||
pKey,type,index,aiPTI_Buffer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,11 +165,13 @@ aiReturn MaterialHelper::AddProperty (const TYPE* pInput,
|
|||
template<>
|
||||
inline aiReturn MaterialHelper::AddProperty<float> (const float* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
return this->AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(float),
|
||||
pKey,aiPTI_Float);
|
||||
pKey,type,index,aiPTI_Float);
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,11 +180,13 @@ inline aiReturn MaterialHelper::AddProperty<float> (const float* pInput,
|
|||
template<>
|
||||
inline aiReturn MaterialHelper::AddProperty<aiColor4D> (const aiColor4D* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
return this->AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiColor4D),
|
||||
pKey,aiPTI_Float);
|
||||
pKey,type,index,aiPTI_Float);
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,11 +195,13 @@ inline aiReturn MaterialHelper::AddProperty<aiColor4D> (const aiColor4D* pInput,
|
|||
template<>
|
||||
inline aiReturn MaterialHelper::AddProperty<aiColor3D> (const aiColor3D* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
return this->AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiColor3D),
|
||||
pKey,aiPTI_Float);
|
||||
pKey,type,index,aiPTI_Float);
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,11 +210,13 @@ inline aiReturn MaterialHelper::AddProperty<aiColor3D> (const aiColor3D* pInput,
|
|||
template<>
|
||||
inline aiReturn MaterialHelper::AddProperty<int> (const int* pInput,
|
||||
const unsigned int pNumValues,
|
||||
const char* pKey)
|
||||
const char* pKey,
|
||||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
return this->AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(int),
|
||||
pKey,aiPTI_Integer);
|
||||
pKey,type,index,aiPTI_Integer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,54 @@ inline VertexWeightTable* ComputeVertexBoneWeightTable(aiMesh* pMesh)
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Get a string for a given aiTextureType
|
||||
inline const char* TextureTypeToString(aiTextureType in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case aiTextureType_DIFFUSE:
|
||||
return "Diffuse";
|
||||
case aiTextureType_SPECULAR:
|
||||
return "Specular";
|
||||
case aiTextureType_AMBIENT:
|
||||
return "Ambient";
|
||||
case aiTextureType_EMISSIVE:
|
||||
return "Emissive";
|
||||
case aiTextureType_OPACITY:
|
||||
return "Opacity";
|
||||
case aiTextureType_NORMALS:
|
||||
return "Normals";
|
||||
case aiTextureType_HEIGHT:
|
||||
return "Height";
|
||||
case aiTextureType_SHININESS:
|
||||
return "Shininess";
|
||||
}
|
||||
return "LARGE ERROR, please leave the room immediately and call the police";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Get a string for a given aiTextureMapping
|
||||
inline const char* MappingTypeToString(aiTextureMapping in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case aiTextureMapping_UV:
|
||||
return "UV";
|
||||
case aiTextureMapping_BOX:
|
||||
return "Box";
|
||||
case aiTextureMapping_SPHERE:
|
||||
return "Sphere";
|
||||
case aiTextureMapping_CYLINDER:
|
||||
return "Cylinder";
|
||||
case aiTextureMapping_PLANE:
|
||||
return "Plane";
|
||||
case aiTextureMapping_OTHER:
|
||||
return "Other";
|
||||
}
|
||||
return "LARGE ERROR, please leave the room immediately and call the police";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class ComputeSpatialSortProcess : public BaseProcess
|
||||
{
|
||||
|
|
|
@ -47,34 +47,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
# define sprintf sprintf_s
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the processing step is present in the given flag field.
|
||||
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
|
||||
{
|
||||
return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("RemoveRedundantMatsProcess begin");
|
||||
|
||||
unsigned int iCnt = 0;
|
||||
unsigned int iCnt = 0, unreferenced = 0;
|
||||
if (pScene->mNumMaterials)
|
||||
{
|
||||
// TODO: reimplement this algorithm to work in-place
|
||||
|
@ -95,7 +95,11 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
|||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||
{
|
||||
// if the material is not referenced ... remove it
|
||||
if (!abReferenced[i])continue;
|
||||
if (!abReferenced[i])
|
||||
{
|
||||
++unreferenced;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t me = aiHashes[i] = ((MaterialHelper*)pScene->mMaterials[i])->ComputeHash();
|
||||
for (unsigned int a = 0; a < i;++a)
|
||||
|
@ -153,7 +157,8 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
|||
else
|
||||
{
|
||||
char szBuffer[128]; // should be sufficiently large
|
||||
::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. Found %i redundant materials",iCnt);
|
||||
::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. %i redundant and %i unused materials",
|
||||
iCnt,unreferenced);
|
||||
DefaultLogger::get()->info(szBuffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ using namespace Assimp;
|
|||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
KeyIterator::KeyIterator(std::vector<aiVectorKey>* _objPos,
|
||||
KeyIterator::KeyIterator(const std::vector<aiVectorKey>* _objPos,
|
||||
const std::vector<aiVectorKey>* _targetObjPos,
|
||||
const aiVector3D* defaultObjectPos /*= NULL*/,
|
||||
const aiVector3D* defaultTargetPos /*= NULL*/)
|
||||
|
@ -58,7 +58,7 @@ KeyIterator::KeyIterator(std::vector<aiVectorKey>* _objPos,
|
|||
, nextTargetObjPos(0)
|
||||
{
|
||||
// Generate default transformation tracks if necessary
|
||||
if (!objPos)
|
||||
if (!objPos || objPos->empty())
|
||||
{
|
||||
defaultObjPos.resize(1);
|
||||
defaultObjPos.front().mTime = 10e10;
|
||||
|
@ -68,7 +68,7 @@ KeyIterator::KeyIterator(std::vector<aiVectorKey>* _objPos,
|
|||
|
||||
objPos = & defaultObjPos;
|
||||
}
|
||||
if (!targetObjPos)
|
||||
if (!targetObjPos || targetObjPos->empty())
|
||||
{
|
||||
defaultTargetObjPos.resize(1);
|
||||
defaultTargetObjPos.front().mTime = 10e10;
|
||||
|
@ -177,23 +177,31 @@ void TargetAnimationHelper::SetTargetAnimationChannel (
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
void TargetAnimationHelper::SetMainAnimationChannel (
|
||||
std::vector<aiVectorKey>* _objectPositions)
|
||||
const std::vector<aiVectorKey>* _objectPositions)
|
||||
{
|
||||
ai_assert(NULL != _objectPositions);
|
||||
objectPositions = _objectPositions;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void TargetAnimationHelper::SetFixedMainAnimationChannel(
|
||||
const aiVector3D& fixed)
|
||||
{
|
||||
objectPositions = NULL; // just to avoid confusion
|
||||
fixedMain = fixed;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack)
|
||||
{
|
||||
ai_assert(NULL != objectPositions);
|
||||
ai_assert(NULL != targetPositions);
|
||||
|
||||
// Iterate through all object keys and interpolate their values if necessary.
|
||||
// Then get the corresponding target position, compute the difference
|
||||
// vector between object and target position. Then compute a rotation matrix
|
||||
// that rotates the base vector of the object coordinate system at that time
|
||||
// to match the diff vector.
|
||||
KeyIterator iter(objectPositions,targetPositions);
|
||||
KeyIterator iter(objectPositions,targetPositions,&fixedMain);
|
||||
unsigned int curTarget;
|
||||
for (;!iter.Finished();++iter)
|
||||
{
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
* @param defaultTargetPos Default target position to be used if
|
||||
* no animated track is available. May be NULL.
|
||||
*/
|
||||
KeyIterator(std::vector<aiVectorKey>* _objPos,
|
||||
KeyIterator(const std::vector<aiVectorKey>* _objPos,
|
||||
const std::vector<aiVectorKey>* _targetObjPos,
|
||||
const aiVector3D* defaultObjectPos = NULL,
|
||||
const aiVector3D* defaultTargetPos = NULL);
|
||||
|
@ -129,7 +129,8 @@ class ASSIMP_API TargetAnimationHelper
|
|||
public:
|
||||
|
||||
TargetAnimationHelper()
|
||||
: objectPositions (NULL)
|
||||
: targetPositions (NULL)
|
||||
, objectPositions (NULL)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -141,8 +142,8 @@ public:
|
|||
*
|
||||
* @param targetPositions Translation channel
|
||||
*/
|
||||
void SetTargetAnimationChannel (
|
||||
const std::vector<aiVectorKey>* targetPositions);
|
||||
void SetTargetAnimationChannel (const
|
||||
std::vector<aiVectorKey>* targetPositions);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
@ -150,9 +151,16 @@ public:
|
|||
*
|
||||
* @param objectPositions Translation channel
|
||||
*/
|
||||
void SetMainAnimationChannel (
|
||||
void SetMainAnimationChannel ( const
|
||||
std::vector<aiVectorKey>* objectPositions);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/** Sets the main animation channel to a fixed value
|
||||
*
|
||||
* @param fixed Fixed value for the main animation channel
|
||||
*/
|
||||
void SetFixedMainAnimationChannel(const aiVector3D& fixed);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/** Computes final animation channels
|
||||
|
@ -163,8 +171,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
const std::vector<aiVectorKey>* targetPositions;
|
||||
std::vector<aiVectorKey> *objectPositions;
|
||||
const std::vector<aiVectorKey>* targetPositions,*objectPositions;
|
||||
aiVector3D fixedMain;
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,56 +38,107 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Definition of a helper class that processes texture transformations */
|
||||
/** @file Definition of a helper step that processes texture transformations */
|
||||
#ifndef AI_TEXTURE_TRANSFORM_H_INCLUDED
|
||||
#define AI_TEXTURE_TRANSFORM_H_INCLUDED
|
||||
|
||||
#include "BaseImporter.h"
|
||||
#include "../include/aiTypes.h"
|
||||
#include "../include/aiMaterial.h"
|
||||
#include "../include/aiMesh.h"
|
||||
|
||||
#include "BaseProcess.h"
|
||||
|
||||
struct aiNode;
|
||||
#include "3DSHelper.h"
|
||||
|
||||
namespace Assimp
|
||||
namespace Assimp {
|
||||
|
||||
#define AI_TT_UV_IDX_LOCK_TBD 0xffffffff
|
||||
#define AI_TT_UV_IDX_LOCK_NONE 0xeeeeeeee
|
||||
|
||||
|
||||
#define AI_TT_ROTATION_EPSILON ((float)AI_DEG_TO_RAD(0.5))
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Small helper structure representing a shortcut into the material list
|
||||
* to be able to update some values quickly.
|
||||
*/
|
||||
struct TTUpdateInfo
|
||||
{
|
||||
TTUpdateInfo()
|
||||
: mat (NULL)
|
||||
, directShortcut (NULL)
|
||||
, semantic (0)
|
||||
, index (0)
|
||||
{}
|
||||
|
||||
//! Direct shortcut, if available
|
||||
unsigned int* directShortcut;
|
||||
|
||||
//! Material
|
||||
MaterialHelper* mat;
|
||||
|
||||
//! Texture type and index
|
||||
unsigned int semantic, index;
|
||||
};
|
||||
|
||||
using namespace Assimp::D3DS;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper class representing texture coordinate transformations
|
||||
*/
|
||||
struct STransformVecInfo
|
||||
struct STransformVecInfo : public aiUVTransform
|
||||
{
|
||||
//! Construction. The resulting matrix is the identity
|
||||
|
||||
STransformVecInfo()
|
||||
:
|
||||
fScaleU(1.0f),fScaleV(1.0f),
|
||||
fOffsetU(0.0f),fOffsetV(0.0f),
|
||||
fRotation(0.0f),
|
||||
iUVIndex(0)
|
||||
: uvIndex (0)
|
||||
, mapU (aiTextureMapMode_Wrap)
|
||||
, mapV (aiTextureMapMode_Wrap)
|
||||
, lockedPos (AI_TT_UV_IDX_LOCK_NONE)
|
||||
{}
|
||||
|
||||
//! Texture coordinate scaling in the x-direction
|
||||
float fScaleU;
|
||||
//! Texture coordinate scaling in the y-direction
|
||||
float fScaleV;
|
||||
//! Texture coordinate offset in the x-direction
|
||||
float fOffsetU;
|
||||
//! Texture coordinate offset in the y-direction
|
||||
float fOffsetV;
|
||||
//! Texture coordinate rotation, clockwise, in radians
|
||||
float fRotation;
|
||||
|
||||
//! Source texture coordinate index
|
||||
unsigned int iUVIndex;
|
||||
unsigned int uvIndex;
|
||||
|
||||
//! Texture mapping mode in the u, v direction
|
||||
aiTextureMapMode mapU,mapV;
|
||||
|
||||
//! Locked destination UV index
|
||||
//! AI_TT_UV_IDX_LOCK_TBD - to be determined
|
||||
//! AI_TT_UV_IDX_LOCK_NONE - none (default)
|
||||
unsigned int lockedPos;
|
||||
|
||||
//! Update info - shortcuts into all materials
|
||||
//! that are referencing this transform setup
|
||||
std::list<TTUpdateInfo> updateList;
|
||||
|
||||
|
||||
//! List of all textures that use this texture
|
||||
//! coordinate transformations
|
||||
std::vector<D3DS::Texture*> pcTextures;
|
||||
// -------------------------------------------------------------------
|
||||
/** Compare two transform setups
|
||||
*/
|
||||
inline bool operator== (const STransformVecInfo& other) const
|
||||
{
|
||||
// We use a small epsilon here
|
||||
const float epsilon = 0.05f;
|
||||
|
||||
if (fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
|
||||
fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fabs( mScaling.x - other.mScaling.x ) > epsilon ||
|
||||
fabs( mScaling.y - other.mScaling.y ) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fabs( mRotation - other.mRotation) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator!= (const STransformVecInfo& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -95,8 +146,9 @@ struct STransformVecInfo
|
|||
*/
|
||||
inline bool IsUntransformed() const
|
||||
{
|
||||
return 1.0f == fScaleU && 1.0f == fScaleV &&
|
||||
!fOffsetU && !fOffsetV && !fRotation;
|
||||
return (1.0f == mScaling.x && 1.f == mScaling.y &&
|
||||
!mTranslation.x && !mTranslation.y &&
|
||||
mRotation < AI_TT_ROTATION_EPSILON);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -106,26 +158,26 @@ struct STransformVecInfo
|
|||
{
|
||||
mOut = aiMatrix3x3();
|
||||
|
||||
if (1.0f != this->fScaleU || 1.0f != this->fScaleV)
|
||||
if (1.0f != mScaling.x || 1.0f != mScaling.y)
|
||||
{
|
||||
aiMatrix3x3 mScale;
|
||||
mScale.a1 = this->fScaleU;
|
||||
mScale.b2 = this->fScaleV;
|
||||
mScale.a1 = mScaling.x;
|
||||
mScale.b2 = mScaling.y;
|
||||
mOut = mScale;
|
||||
}
|
||||
if (this->fRotation)
|
||||
if (mRotation)
|
||||
{
|
||||
aiMatrix3x3 mRot;
|
||||
mRot.a1 = mRot.b2 = cosf(this->fRotation);
|
||||
mRot.a2 = mRot.b1 = sinf(this->fRotation);
|
||||
mRot.a1 = mRot.b2 = cos(mRotation);
|
||||
mRot.a2 = mRot.b1 = sin(mRotation);
|
||||
mRot.a2 = -mRot.a2;
|
||||
mOut *= mRot;
|
||||
}
|
||||
if (this->fOffsetU || this->fOffsetV)
|
||||
if (mTranslation.x || mTranslation.y)
|
||||
{
|
||||
aiMatrix3x3 mTrans;
|
||||
mTrans.a3 = this->fOffsetU;
|
||||
mTrans.b3 = this->fOffsetV;
|
||||
mTrans.a3 = mTranslation.x;
|
||||
mTrans.b3 = mTranslation.y;
|
||||
mOut *= mTrans;
|
||||
}
|
||||
}
|
||||
|
@ -133,73 +185,39 @@ struct STransformVecInfo
|
|||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper class used by the ASE/ASK and 3DS loaders to handle texture
|
||||
* coordinate transformations correctly (such as offsets, scaling)
|
||||
/** Helper step to compute final UV coordinate sets if there are scalings
|
||||
* or rotations in the original data read from the file.
|
||||
*/
|
||||
class ASSIMP_API TextureTransform
|
||||
class ASSIMP_API TextureTransformStep : public BaseProcess
|
||||
{
|
||||
//! Constructor, it is not possible to create instances of this class
|
||||
TextureTransform() {}
|
||||
public:
|
||||
|
||||
TextureTransformStep();
|
||||
~TextureTransformStep();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns true if a texture requires UV transformations
|
||||
* \param rcIn Input texture
|
||||
*/
|
||||
inline static bool HasUVTransform(
|
||||
const D3DS::Texture& rcIn)
|
||||
{
|
||||
return (rcIn.mOffsetU || rcIn.mOffsetV ||
|
||||
1.0f != rcIn.mScaleU || 1.0f != rcIn.mScaleV || rcIn.mRotation);
|
||||
}
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Must be called before HasUVTransform(rcIn) is called
|
||||
* \param rcIn Input texture
|
||||
*/
|
||||
static void PreProcessUVTransform(
|
||||
D3DS::Texture& rcIn);
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Check whether the texture coordinate transformation of
|
||||
* a texture is already contained in a given list
|
||||
* \param rasVec List of transformations
|
||||
* \param pcTex Pointer to the texture
|
||||
*/
|
||||
static void AddToList(std::vector<STransformVecInfo>& rasVec,
|
||||
D3DS::Texture* pcTex);
|
||||
void SetupProperties(const Importer* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a full list of all texture coordinate offsets required
|
||||
* for a material
|
||||
* \param materials List of materials to be processed
|
||||
*/
|
||||
static void ApplyScaleNOffset(std::vector<D3DS::Material>& materials);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a full list of all texture coordinate offsets required
|
||||
* for a material
|
||||
* \param material Material to be processed
|
||||
*/
|
||||
static void ApplyScaleNOffset(D3DS::Material& material);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Precompute as many texture coordinate transformations as possible
|
||||
* \param pcMesh Mesh containing the texture coordinate data
|
||||
* \param pcSrc Input material. Must have been passed to
|
||||
* ApplyScaleNOffset
|
||||
*/
|
||||
static void BakeScaleNOffset(aiMesh* pcMesh, D3DS::Material* pcSrc);
|
||||
protected:
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Setup the correct UV source for a material
|
||||
* \param pcMat Final material to be changed
|
||||
* \param pcMatIn Input material, unconverted
|
||||
/** Preprocess a specific UV transformation setup
|
||||
*
|
||||
* @param info Transformation setup to be preprocessed.
|
||||
*/
|
||||
static void SetupMatUVSrc (aiMaterial* pcMat,
|
||||
const D3DS::Material* pcMatIn);
|
||||
void PreProcessUVTransform(STransformVecInfo& info);
|
||||
|
||||
private:
|
||||
|
||||
unsigned int configFlags;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -418,7 +418,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
|||
{
|
||||
if (face.mIndices[a] >= pMesh->mNumVertices)
|
||||
{
|
||||
this->ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
|
||||
ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
|
||||
}
|
||||
// the MSB flag is temporarily used by the extra verbose
|
||||
// mode to tell us that the JoinVerticesProcess might have
|
||||
|
@ -523,6 +523,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
|||
ReportError("aiMesh::mBones is non-null although there are no bones");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiMesh* pMesh,
|
||||
const aiBone* pBone,float* afSum)
|
||||
|
@ -548,6 +549,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh,
|
|||
afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
|
||||
{
|
||||
|
@ -576,36 +578,54 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
|
|||
// Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
|
||||
// if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
|
||||
const char* szType)
|
||||
aiTextureType type)
|
||||
{
|
||||
ai_assert(NULL != szType);
|
||||
const char* szType;
|
||||
switch (type)
|
||||
{
|
||||
case aiTextureType_DIFFUSE:
|
||||
szType = "Diffuse";break;
|
||||
|
||||
// search all keys of the material ...
|
||||
// textures must be specified with rising indices (e.g. diffuse #2 may not be
|
||||
// specified if diffuse #1 is not there ...)
|
||||
case aiTextureType_SPECULAR:
|
||||
szType = "Specular";break;
|
||||
|
||||
// "$tex.file.<szType>[<index>]"
|
||||
char szBaseBuf[512];
|
||||
int iLen;
|
||||
iLen = ::sprintf(szBaseBuf,"$tex.file.%s",szType);
|
||||
if (0 >= iLen)return;
|
||||
case aiTextureType_AMBIENT:
|
||||
szType = "Ambient";break;
|
||||
|
||||
case aiTextureType_EMISSIVE:
|
||||
szType = "Emissive";break;
|
||||
|
||||
case aiTextureType_OPACITY:
|
||||
szType = "Opacity";break;
|
||||
|
||||
case aiTextureType_SHININESS:
|
||||
szType = "Shininess";break;
|
||||
|
||||
case aiTextureType_NORMALS:
|
||||
szType = "Normals";break;
|
||||
|
||||
case aiTextureType_HEIGHT:
|
||||
szType = "Height";break;
|
||||
};
|
||||
|
||||
// ****************************************************************************
|
||||
// Search all keys of the material ...
|
||||
// textures must be specified with ascending indices
|
||||
// (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
|
||||
// ****************************************************************************
|
||||
|
||||
int iNumIndices = 0;
|
||||
int iIndex = -1;
|
||||
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
|
||||
{
|
||||
aiMaterialProperty* prop = pMaterial->mProperties[i];
|
||||
if (0 == ASSIMP_strincmp( prop->mKey.data, szBaseBuf, iLen ))
|
||||
if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type)
|
||||
{
|
||||
const char* sz = &prop->mKey.data[iLen];
|
||||
if (*sz)
|
||||
{
|
||||
++sz;
|
||||
iIndex = std::max(iIndex, (int)strtol10(sz,0));
|
||||
iIndex = std::max(iIndex, (int) prop->mIndex);
|
||||
++iNumIndices;
|
||||
}
|
||||
|
||||
if (aiPTI_String != prop->mType)
|
||||
this->ReportError("Material property %s is expected to be a string",prop->mKey.data);
|
||||
|
@ -613,63 +633,84 @@ void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
|
|||
}
|
||||
if (iIndex +1 != iNumIndices)
|
||||
{
|
||||
this->ReportError("%s #%i is set, but there are only %i %s textures",
|
||||
ReportError("%s #%i is set, but there are only %i %s textures",
|
||||
szType,iIndex,iNumIndices,szType);
|
||||
}
|
||||
if (!iNumIndices)return;
|
||||
|
||||
// now check whether all UV indices are valid ...
|
||||
iLen = ::sprintf(szBaseBuf,"$tex.uvw.%s",szType);
|
||||
if (0 >= iLen)return;
|
||||
// TODO: check whether the mappings are correctly
|
||||
std::vector<aiTextureMapping> mappings(iNumIndices);
|
||||
|
||||
// Now check whether all UV indices are valid ...
|
||||
bool bNoSpecified = true;
|
||||
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
|
||||
{
|
||||
aiMaterialProperty* prop = pMaterial->mProperties[i];
|
||||
if (0 == ASSIMP_strincmp( prop->mKey.data, szBaseBuf, iLen ))
|
||||
if (prop->mSemantic != type)continue;
|
||||
|
||||
if ((int)prop->mIndex >= iNumIndices)
|
||||
{
|
||||
ReportError("Found texture property with index %i, although there "
|
||||
"are only %i textures of type %s",
|
||||
prop->mIndex, iNumIndices, szType);
|
||||
}
|
||||
|
||||
if (!::strcmp(prop->mKey.data,"$tex.mapping"))
|
||||
{
|
||||
if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping))
|
||||
{
|
||||
ReportError("Material property %s%i is expected to be an integer (size is %i)",
|
||||
prop->mKey.data,prop->mIndex,prop->mDataLength);
|
||||
}
|
||||
mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
|
||||
}
|
||||
else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo"))
|
||||
{
|
||||
if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform))
|
||||
{
|
||||
ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
|
||||
prop->mKey.data,prop->mIndex, prop->mDataLength);
|
||||
}
|
||||
mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
|
||||
}
|
||||
else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc"))
|
||||
{
|
||||
if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength)
|
||||
this->ReportError("Material property %s is expected to be an integer",prop->mKey.data);
|
||||
|
||||
const char* sz = &prop->mKey.data[iLen];
|
||||
if (*sz)
|
||||
{
|
||||
++sz;
|
||||
iIndex = strtol10(sz,NULL);
|
||||
ReportError("Material property %s%i is expected to be an integer (size is %i)",
|
||||
prop->mKey.data,prop->mIndex,prop->mDataLength);
|
||||
}
|
||||
bNoSpecified = false;
|
||||
|
||||
// ignore UV indices for texture channel that are not there ...
|
||||
if (iIndex >= iNumIndices)
|
||||
{
|
||||
// get the value
|
||||
// Ignore UV indices for texture channels that are not there ...
|
||||
|
||||
// Get the value
|
||||
iIndex = *((unsigned int*)prop->mData);
|
||||
|
||||
// check whether there is a mesh using this material
|
||||
// Check whether there is a mesh using this material
|
||||
// which has not enough UV channels ...
|
||||
for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
|
||||
{
|
||||
aiMesh* mesh = this->mScene->mMeshes[a];
|
||||
if(mesh->mMaterialIndex == (unsigned int)iIndex)
|
||||
if(mesh->mMaterialIndex == (unsigned int)i)
|
||||
{
|
||||
int iChannels = 0;
|
||||
while (mesh->HasTextureCoords(iChannels))++iChannels;
|
||||
if (iIndex >= iChannels)
|
||||
{
|
||||
this->ReportError("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
|
||||
ReportError("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
|
||||
iIndex,prop->mKey.data,a,iChannels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bNoSpecified)
|
||||
{
|
||||
// Assume that all textures are using the first UV channel
|
||||
for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
|
||||
{
|
||||
aiMesh* mesh = this->mScene->mMeshes[a];
|
||||
aiMesh* mesh = mScene->mMeshes[a];
|
||||
if(mesh->mMaterialIndex == (unsigned int)iIndex)
|
||||
{
|
||||
if (!mesh->mTextureCoords[0])
|
||||
|
@ -766,15 +807,16 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
|
|||
}
|
||||
|
||||
// check whether there are invalid texture keys
|
||||
SearchForInvalidTextures(pMaterial,"diffuse");
|
||||
SearchForInvalidTextures(pMaterial,"specular");
|
||||
SearchForInvalidTextures(pMaterial,"ambient");
|
||||
SearchForInvalidTextures(pMaterial,"emissive");
|
||||
SearchForInvalidTextures(pMaterial,"opacity");
|
||||
SearchForInvalidTextures(pMaterial,"shininess");
|
||||
SearchForInvalidTextures(pMaterial,"normals");
|
||||
SearchForInvalidTextures(pMaterial,"height");
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT);
|
||||
SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiTexture* pTexture)
|
||||
{
|
||||
|
@ -814,35 +856,13 @@ void ValidateDSProcess::Validate( const aiTexture* pTexture)
|
|||
this->ReportError("aiTexture::achFormatHint contains non-lowercase characters");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
|
||||
const aiNodeAnim* pNodeAnim)
|
||||
{
|
||||
this->Validate(&pNodeAnim->mNodeName);
|
||||
Validate(&pNodeAnim->mNodeName);
|
||||
|
||||
#if 0
|
||||
// check whether there is a bone with this name ...
|
||||
unsigned int i = 0;
|
||||
for (; i < this->mScene->mNumMeshes;++i)
|
||||
{
|
||||
aiMesh* mesh = this->mScene->mMeshes[i];
|
||||
for (unsigned int a = 0; a < mesh->mNumBones;++a)
|
||||
{
|
||||
if (mesh->mBones[a]->mName == pNodeAnim->mBoneName)
|
||||
goto __break_out;
|
||||
}
|
||||
}
|
||||
__break_out:
|
||||
if (i == this->mScene->mNumMeshes)
|
||||
{
|
||||
this->ReportWarning("aiNodeAnim::mBoneName is \"%s\". However, no bone with this name was found",
|
||||
pNodeAnim->mBoneName.data);
|
||||
}
|
||||
if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mNumRotationKeys && !pNodeAnim->mNumScalingKeys)
|
||||
{
|
||||
this->ReportWarning("A bone animation channel has no keys");
|
||||
}
|
||||
#endif
|
||||
// otherwise check whether one of the keys exceeds the total duration of the animation
|
||||
if (pNodeAnim->mNumPositionKeys)
|
||||
{
|
||||
|
@ -934,11 +954,12 @@ __break_out:
|
|||
ReportError("A node animation channel must have at least one subtrack");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiNode* pNode)
|
||||
{
|
||||
if (!pNode)this->ReportError("A node of the scenegraph is NULL");
|
||||
if (pNode != this->mScene->mRootNode && !pNode->mParent)
|
||||
if (!pNode)ReportError("A node of the scenegraph is NULL");
|
||||
if (pNode != mScene->mRootNode && !pNode->mParent)
|
||||
this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
|
||||
|
||||
this->Validate(&pNode->mName);
|
||||
|
@ -948,21 +969,21 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
|
|||
{
|
||||
if (!pNode->mMeshes)
|
||||
{
|
||||
this->ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
|
||||
ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
|
||||
pNode->mNumMeshes);
|
||||
}
|
||||
std::vector<bool> abHadMesh;
|
||||
abHadMesh.resize(this->mScene->mNumMeshes,false);
|
||||
abHadMesh.resize(mScene->mNumMeshes,false);
|
||||
for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
|
||||
{
|
||||
if (pNode->mMeshes[i] >= this->mScene->mNumMeshes)
|
||||
if (pNode->mMeshes[i] >= mScene->mNumMeshes)
|
||||
{
|
||||
this->ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
|
||||
pNode->mMeshes[i],this->mScene->mNumMeshes-1);
|
||||
ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
|
||||
pNode->mMeshes[i],mScene->mNumMeshes-1);
|
||||
}
|
||||
if (abHadMesh[pNode->mMeshes[i]])
|
||||
{
|
||||
this->ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
|
||||
ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
|
||||
i,pNode->mMeshes[i]);
|
||||
}
|
||||
abHadMesh[pNode->mMeshes[i]] = true;
|
||||
|
@ -977,10 +998,11 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
|
|||
}
|
||||
for (unsigned int i = 0; i < pNode->mNumChildren;++i)
|
||||
{
|
||||
this->Validate(pNode->mChildren[i]);
|
||||
Validate(pNode->mChildren[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ValidateDSProcess::Validate( const aiString* pString)
|
||||
{
|
||||
|
@ -995,11 +1017,11 @@ void ValidateDSProcess::Validate( const aiString* pString)
|
|||
if ('\0' == *sz)
|
||||
{
|
||||
if (pString->length != (unsigned int)(sz-pString->data))
|
||||
this->ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
|
||||
ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
|
||||
break;
|
||||
}
|
||||
else if (sz >= &pString->data[MAXLEN])
|
||||
this->ReportError("aiString::data is invalid. There is no terminal character");
|
||||
ReportError("aiString::data is invalid. There is no terminal character");
|
||||
++sz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,11 +134,10 @@ protected:
|
|||
/** Search the material data structure for invalid or corrupt
|
||||
* texture keys.
|
||||
* @param pMaterial Input material
|
||||
* @param szType Type of the texture (the purpose string that
|
||||
* occurs in material keys, e.g. "diffuse", "ambient")
|
||||
* @param type Type of the texture
|
||||
*/
|
||||
void SearchForInvalidTextures(const aiMaterial* pMaterial,
|
||||
const char* szType);
|
||||
aiTextureType type);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Validates a texture
|
||||
|
|
|
@ -611,7 +611,6 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
|||
std::string sz = otex.mName;
|
||||
if (!sz.length())continue;
|
||||
|
||||
char key[256];
|
||||
|
||||
// find the file name
|
||||
const size_t iLen = sz.length();
|
||||
|
@ -634,35 +633,35 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
|||
if( isalpha( sz[c]))
|
||||
sz[c] = tolower( sz[c]);
|
||||
|
||||
|
||||
// Place texture filename property under the corresponding name
|
||||
aiString tex( oldMat.mTextures[b].mName);
|
||||
|
||||
// bump map
|
||||
if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s))
|
||||
{
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++));
|
||||
} else
|
||||
if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s))
|
||||
{
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++));
|
||||
} else
|
||||
if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s))
|
||||
{
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++));
|
||||
} else
|
||||
if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s))
|
||||
{
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++));
|
||||
} else
|
||||
if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s))
|
||||
{
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++));
|
||||
} else
|
||||
{
|
||||
// assume it is a diffuse texture
|
||||
::sprintf(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
||||
// Assume it is a diffuse texture
|
||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++));
|
||||
}
|
||||
|
||||
// place texture filename property under the corresponding name
|
||||
aiString tex( oldMat.mTextures[b].mName);
|
||||
mat->AddProperty( &tex, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,10 @@ SOURCES = AssimpPCH.cpp \
|
|||
Q3DLoader.cpp \
|
||||
ScenePreprocessor.cpp \
|
||||
B3DImporter.cpp \
|
||||
TargetAnimation.cpp
|
||||
TargetAnimation.cpp \
|
||||
ComputeUVMappingProcess.cpp \
|
||||
ColladaLoader.cpp \
|
||||
ColladaParser.cpp
|
||||
|
||||
OBJECTS = $(SOURCES:.cpp=.o)
|
||||
|
||||
|
|
|
@ -74,8 +74,10 @@ SOURCES = AssimpPCH.cpp \
|
|||
Q3DLoader.cpp \
|
||||
ScenePreprocessor.cpp \
|
||||
B3DImporter.cpp \
|
||||
TargetAnimation.cpp
|
||||
|
||||
TargetAnimation.cpp \
|
||||
ComputeUVMappingProcess.cpp \
|
||||
ColladaLoader.cpp \
|
||||
ColladaParser.cpp
|
||||
|
||||
OBJECTS = $(SOURCES:.cpp=.o)
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
||||
#define __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
||||
|
||||
#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// small replacement for boost::scoped_array
|
||||
template <class T>
|
||||
class scoped_array
|
||||
{
|
||||
public:
|
||||
|
||||
// provide a default construtctor
|
||||
scoped_array()
|
||||
: ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
// construction from an existing heap object of type T
|
||||
scoped_array(T* _ptr)
|
||||
: ptr(_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
// automatic destruction of the wrapped object at the
|
||||
// end of our lifetime
|
||||
~scoped_array()
|
||||
{
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
inline T* get()
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline operator T*()
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline T* operator-> ()
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void reset (T* t = 0)
|
||||
{
|
||||
delete[] ptr;
|
||||
ptr = t;
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const
|
||||
{
|
||||
return ptr[i];
|
||||
}
|
||||
|
||||
void swap(scoped_array & b)
|
||||
{
|
||||
std::swap(ptr, b.ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// encapsulated object pointer
|
||||
T* ptr;
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline void swap(scoped_array<T> & a, scoped_array<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // end of namespace boost
|
||||
|
||||
#else
|
||||
# error "scoped_array.h was already included"
|
||||
#endif
|
||||
#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
|
@ -16,7 +16,7 @@ public:
|
|||
|
||||
// provide a default construtctor
|
||||
scoped_ptr()
|
||||
: ptr(NULL)
|
||||
: ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,17 @@ public:
|
|||
return ptr;
|
||||
}
|
||||
|
||||
inline void reset (T* t = 0)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = t;
|
||||
}
|
||||
|
||||
void swap(scoped_ptr & b)
|
||||
{
|
||||
std::swap(ptr, b.ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// encapsulated object pointer
|
||||
|
@ -55,6 +66,12 @@ private:
|
|||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // end of namespace boost
|
||||
|
||||
#else
|
||||
|
|
|
@ -55,6 +55,12 @@ extern "C" {
|
|||
/** Helper structure to describe a virtual camera.
|
||||
*
|
||||
* Cameras have a representation in the node graph and can be animated.
|
||||
* Note - some file formats (such as 3DS, ASE) export a "target point" -
|
||||
* the point the camera is looking at (it can even be animated). Assimp
|
||||
* writes the target point as a subnode of the camera's main node,
|
||||
* called "<camName>.Target". However, this is just additional information
|
||||
* then, the transformation tracks of the camera main node make the
|
||||
* camera already point in the right direction.
|
||||
*
|
||||
*/
|
||||
struct aiCamera
|
||||
|
|
|
@ -101,15 +101,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define AI_CONFIG_IMPORT_SMD_KEYFRAME "imp.smd.kf"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Configures the 3DS loader to ignore pivot points in the file
|
||||
*
|
||||
* There are some faulty 3DS files which look only correctly with
|
||||
* pivot points disabled.
|
||||
* Property type: integer (0: false; !0: true). Default value: false.
|
||||
*/
|
||||
#define AI_CONFIG_IMPORT_3DS_IGNORE_PIVOT "imp.3ds.nopivot"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Configures the AC loader to collect all surfaces which have the
|
||||
|
@ -305,6 +296,23 @@ enum aiComponent
|
|||
#define AI_CONFIG_PP_SBP_REMOVE "pp.sbp.remove"
|
||||
|
||||
|
||||
|
||||
#define AI_UVTRAFO_SCALING 0x1
|
||||
#define AI_UVTRAFO_ROTATION 0x2
|
||||
#define AI_UVTRAFO_TRANSLATION 0x4
|
||||
#define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Input parameter to the #aiProcess_TransformUVCoords step:
|
||||
* Specifies which UV transformations are evaluated.
|
||||
*
|
||||
* This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer
|
||||
* property, of course). By default all transformations are enabled
|
||||
* (AI_UVTRAFO_ALL).
|
||||
*/
|
||||
#define AI_CONFIG_PP_TUV_EVALUATE "pp.tuv.process"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \brief Causes assimp to favour speed against import quality.
|
||||
*
|
||||
|
|
|
@ -78,6 +78,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// OPTIMIZEGRAPH
|
||||
// SORTBYPTYPE
|
||||
// FINDINVALIDDATA
|
||||
// TRANSFORMTEXCOORDS
|
||||
// GENUVCOORDS
|
||||
// ************************************************************
|
||||
|
||||
|
||||
|
|
|
@ -87,6 +87,12 @@ enum aiLightSourceType
|
|||
* Assimp supports multiple sorts of light sources, including
|
||||
* directional, point and spot lights. All of them are defined with just
|
||||
* a single structure and distinguished by their parameters.
|
||||
* Note - some file formats (such as 3DS, ASE) export a "target point" -
|
||||
* the point a spot light is looking at (it can even be animated). Assimp
|
||||
* writes the target point as a subnode of a spotlights's main node,
|
||||
* called "<spotName>.Target". However, this is just additional information
|
||||
* then, the transformation tracks of the main node make the
|
||||
* spot light already point in the right direction.
|
||||
*/
|
||||
struct aiLight
|
||||
{
|
||||
|
|
1163
include/aiMaterial.h
1163
include/aiMaterial.h
File diff suppressed because it is too large
Load Diff
|
@ -47,26 +47,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define AI_MATERIAL_INL_INC
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline aiReturn aiMaterial::GetTexture(unsigned int iIndex,
|
||||
unsigned int iTexType,
|
||||
aiString* szPath,
|
||||
unsigned int* piUVIndex ,
|
||||
float* pfBlendFactor ,
|
||||
aiTextureOp* peTextureOp ,
|
||||
aiTextureMapMode* peMapMode )
|
||||
inline aiReturn aiMaterial::GetTexture( aiTextureType type,
|
||||
unsigned int idx,
|
||||
C_STRUCT aiString* path,
|
||||
aiTextureMapping* mapping /*= NULL*/,
|
||||
unsigned int* uvindex /*= NULL*/,
|
||||
float* blend /*= NULL*/,
|
||||
aiTextureOp* op /*= NULL*/,
|
||||
aiTextureMapMode* mapmode /*= NULL*/)
|
||||
{
|
||||
return aiGetMaterialTexture(this,iIndex,iTexType,szPath,
|
||||
piUVIndex,pfBlendFactor,peTextureOp,peMapMode);
|
||||
return aiGetMaterialTexture(this,type,idx,path,mapping,uvindex,blend,op,mapmode);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename Type>
|
||||
inline aiReturn aiMaterial::Get(const char* pKey,Type* pOut,
|
||||
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||
unsigned int idx, Type* pOut,
|
||||
unsigned int* pMax)
|
||||
{
|
||||
unsigned int iNum = pMax ? *pMax : 1;
|
||||
|
||||
aiMaterialProperty* prop;
|
||||
aiReturn ret = aiGetMaterialProperty(this,pKey,&prop);
|
||||
aiReturn ret = aiGetMaterialProperty(this,pKey,type,idx,&prop);
|
||||
if ( AI_SUCCESS == ret )
|
||||
{
|
||||
if (prop->mDataLength < sizeof(Type)*iNum)return AI_FAILURE;
|
||||
|
@ -78,12 +80,14 @@ inline aiReturn aiMaterial::Get(const char* pKey,Type* pOut,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename Type>
|
||||
inline aiReturn aiMaterial::Get(const char* pKey,Type& pOut)
|
||||
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
|
||||
unsigned int idx,Type& pOut)
|
||||
{
|
||||
aiMaterialProperty* prop;
|
||||
aiReturn ret = aiGetMaterialProperty(this,pKey,&prop);
|
||||
aiReturn ret = aiGetMaterialProperty(this,pKey,type,idx,&prop);
|
||||
if ( AI_SUCCESS == ret )
|
||||
{
|
||||
if (prop->mDataLength < sizeof(Type))return AI_FAILURE;
|
||||
|
@ -93,43 +97,50 @@ inline aiReturn aiMaterial::Get(const char* pKey,Type& pOut)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,float* pOut,
|
||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,float* pOut,
|
||||
unsigned int* pMax)
|
||||
{
|
||||
return aiGetMaterialFloatArray(this,pKey,pOut,pMax);
|
||||
return aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,int* pOut,
|
||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,int* pOut,
|
||||
unsigned int* pMax)
|
||||
{
|
||||
return aiGetMaterialIntegerArray(this,pKey,pOut,pMax);
|
||||
return aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,float& pOut)
|
||||
inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,float& pOut)
|
||||
{
|
||||
return aiGetMaterialFloat(this,pKey,&pOut);
|
||||
return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,int& pOut)
|
||||
inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,int& pOut)
|
||||
{
|
||||
return aiGetMaterialInteger(this,pKey,&pOut);
|
||||
return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,aiColor4D& pOut)
|
||||
inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,aiColor4D& pOut)
|
||||
{
|
||||
return aiGetMaterialColor(this,pKey,&pOut);
|
||||
return aiGetMaterialColor(this,pKey,type,idx,&pOut);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
inline aiReturn aiMaterial::Get<aiString>(const char* pKey,aiString& pOut)
|
||||
inline aiReturn aiMaterial::Get<aiString>(const char* pKey,unsigned int type,
|
||||
unsigned int idx,aiString& pOut)
|
||||
{
|
||||
return aiGetMaterialString(this,pKey,&pOut);
|
||||
return aiGetMaterialString(this,pKey,type,idx,&pOut);
|
||||
}
|
||||
|
||||
#endif //! AI_MATERIAL_INL_INC
|
||||
|
|
|
@ -48,11 +48,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct aiMatrix4x4;
|
||||
struct aiVector2D;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a row-major 3x3 matrix
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiMatrix3x3
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -77,6 +77,22 @@ struct aiMatrix3x3
|
|||
aiMatrix3x3 operator* (const aiMatrix3x3& m) const;
|
||||
aiMatrix3x3& Transpose();
|
||||
|
||||
|
||||
/** \brief Returns a rotation matrix
|
||||
* \param a Rotation angle, in radians
|
||||
* \param out Receives the output matrix
|
||||
* \return Reference to the output matrix
|
||||
*/
|
||||
static aiMatrix3x3& Rotation(float a, aiMatrix3x3& out);
|
||||
|
||||
|
||||
/** \brief Returns a translation matrix
|
||||
* \param v Translation vector
|
||||
* \param out Receives the output matrix
|
||||
* \return Reference to the output matrix
|
||||
*/
|
||||
static aiMatrix3x3& Translation( const aiVector2D& v, aiMatrix3x3& out);
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,27 @@ inline aiMatrix3x3& aiMatrix3x3::Transpose()
|
|||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline aiMatrix3x3& aiMatrix3x3::Rotation(float a, aiMatrix3x3& out)
|
||||
{
|
||||
out.a1 = out.b2 = ::cos(a);
|
||||
out.b1 = ::sin(a);
|
||||
out.a2 = - out.b1;
|
||||
|
||||
out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
|
||||
out.c3 = 1.f;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline aiMatrix3x3& aiMatrix3x3::Translation( const aiVector2D& v, aiMatrix3x3& out)
|
||||
{
|
||||
out = aiMatrix3x3();
|
||||
out.a3 = v.x;
|
||||
out.b3 = v.y;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
#endif // __cplusplus
|
||||
|
|
|
@ -504,6 +504,23 @@ struct aiMesh
|
|||
else
|
||||
return mTextureCoords[pIndex] != NULL && mNumVertices > 0;
|
||||
}
|
||||
|
||||
//! Get the number of UV channels the mesh contains
|
||||
inline unsigned int GetNumUVChannels() const
|
||||
{
|
||||
unsigned int n = 0;
|
||||
while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n])++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Get the number of vertex color channels the mesh contains
|
||||
inline unsigned int GetNumColorChannels() const
|
||||
{
|
||||
unsigned int n = 0;
|
||||
while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n])++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
//! Check whether the mesh contains bones
|
||||
inline bool HasBones() const
|
||||
{ return mBones != NULL && mNumBones > 0; }
|
||||
|
|
|
@ -230,7 +230,6 @@ enum aiPostProcessSteps
|
|||
*/
|
||||
aiProcess_FindDegenerates = 0x10000,
|
||||
|
||||
|
||||
/** This step searches all meshes for invalid data, such as zeroed
|
||||
* normal vectors or invalid UV coords and removes them.
|
||||
*
|
||||
|
@ -240,6 +239,26 @@ enum aiPostProcessSteps
|
|||
* The step will also remove meshes that are infinitely small.
|
||||
*/
|
||||
aiProcess_FindInvalidData = 0x20000,
|
||||
|
||||
/** This step converts non-UV mappings (such as spherical or
|
||||
* cylindrical) to proper UV mapping channels.
|
||||
*
|
||||
* Most applications will support UV mapping only, so you will
|
||||
* propably want to specify this step in every case.
|
||||
*/
|
||||
aiProcess_GenUVCoords = 0x40000,
|
||||
|
||||
/** This step pretransforms UV coordinates by the UV transformations
|
||||
* (such as scalings or rotations).
|
||||
*
|
||||
* UV transformations are specified per-texture - see the
|
||||
* AI_MATKEY_UVTRANSFORM key for more information on this topic.
|
||||
* This step finds all textures with transformed input UV
|
||||
* coordinates and generates a new, transformed, UV channel for it.
|
||||
* Most applications won't support UV transformations, so you will
|
||||
* propably want to specify this step in every case.
|
||||
*/
|
||||
aiProcess_TransformUVCoords = 0x80000,
|
||||
};
|
||||
|
||||
|
||||
|
@ -254,7 +273,8 @@ enum aiPostProcessSteps
|
|||
aiProcess_CalcTangentSpace | \
|
||||
aiProcess_GenNormals | \
|
||||
aiProcess_JoinIdenticalVertices | \
|
||||
aiProcess_Triangulate
|
||||
aiProcess_Triangulate | \
|
||||
aiProcess_GenUVCoords
|
||||
|
||||
|
||||
/** @def AI_POSTPROCESS_DEFAULT_REALTIME
|
||||
|
@ -274,7 +294,8 @@ enum aiPostProcessSteps
|
|||
aiProcess_RemoveRedundantMaterials | \
|
||||
aiProcess_SplitLargeMeshes | \
|
||||
aiProcess_OptimizeGraph | \
|
||||
aiProcess_Triangulate
|
||||
aiProcess_Triangulate | \
|
||||
aiProcess_GenUVCoords
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -47,13 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "aiDefines.h"
|
||||
|
||||
// include math helper classes and their implementations
|
||||
// include math helper classes
|
||||
#include "aiVector3D.h"
|
||||
#include "aiMatrix3x3.h"
|
||||
#include "aiMatrix4x4.h"
|
||||
#include "aiVector3D.inl"
|
||||
#include "aiMatrix3x3.inl"
|
||||
#include "aiMatrix4x4.inl"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <string>
|
||||
|
@ -72,7 +69,6 @@ const size_t MAXLEN = 1024;
|
|||
// ---------------------------------------------------------------------------
|
||||
/** Represents a two-dimensional vector.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiVector2D
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -86,6 +82,25 @@ struct aiVector2D
|
|||
float x, y;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a plane in a three-dimensional, euclidean space
|
||||
*/
|
||||
struct aiPlane
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
aiPlane () : a(0.f), b(0.f), c(0.f), d(0.f) {}
|
||||
aiPlane (float _a, float _b, float _c, float _d)
|
||||
: a(_a), b(_b), c(_c), d(_d) {}
|
||||
|
||||
aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {}
|
||||
|
||||
#endif // !__cplusplus
|
||||
|
||||
//! Plane equation
|
||||
float a,b,c,d;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// aiVector3D type moved to separate header due to size of operators
|
||||
// aiQuaternion type moved to separate header due to size of operators
|
||||
// aiMatrix4x4 type moved to separate header due to size of operators
|
||||
|
@ -93,7 +108,6 @@ struct aiVector2D
|
|||
// ---------------------------------------------------------------------------
|
||||
/** Represents a color in Red-Green-Blue space.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiColor3D
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -136,7 +150,6 @@ struct aiColor3D
|
|||
/** Represents a color in Red-Green-Blue space including an
|
||||
* alpha component.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiColor4D
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -157,7 +170,7 @@ struct aiColor4D
|
|||
|
||||
inline bool IsBlack() const
|
||||
{
|
||||
// the alpha component doesn't care here. black is black.
|
||||
// The alpha component doesn't care here. black is black.
|
||||
return !r && !g && !b;
|
||||
}
|
||||
|
||||
|
@ -173,7 +186,6 @@ struct aiColor4D
|
|||
// ---------------------------------------------------------------------------
|
||||
/** Represents a string, zero byte terminated
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiString
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -188,7 +200,7 @@ struct aiString
|
|||
length(rOther.length)
|
||||
{
|
||||
::memcpy( data, rOther.data, rOther.length);
|
||||
this->data[this->length] = '\0';
|
||||
data[length] = '\0';
|
||||
}
|
||||
|
||||
//! Constructor from std::string
|
||||
|
@ -212,17 +224,36 @@ struct aiString
|
|||
//! comparison operator
|
||||
bool operator==(const aiString& other) const
|
||||
{
|
||||
return (this->length == other.length &&
|
||||
return (length == other.length &&
|
||||
0 == strcmp(this->data,other.data));
|
||||
}
|
||||
|
||||
//! inverse comparison operator
|
||||
bool operator!=(const aiString& other) const
|
||||
{
|
||||
return (this->length != other.length ||
|
||||
return (length != other.length ||
|
||||
0 != ::strcmp(this->data,other.data));
|
||||
}
|
||||
|
||||
//! Append a string to the string
|
||||
inline void Append (const char* app)
|
||||
{
|
||||
const size_t len = ::strlen(app);
|
||||
if (!len)return;
|
||||
|
||||
if (length + len >= MAXLEN)
|
||||
return;
|
||||
|
||||
::memcpy(&data[length],app,len+1);
|
||||
length += len;
|
||||
}
|
||||
|
||||
//! Clear the string
|
||||
inline void Clear ()
|
||||
{
|
||||
length = 0;
|
||||
data[0] = '\0';
|
||||
}
|
||||
|
||||
#endif // !__cplusplus
|
||||
|
||||
|
@ -240,18 +271,21 @@ struct aiString
|
|||
* To check whether or not a function failed check against
|
||||
* AI_SUCCESS. The error codes are mainly used by the C-API.
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
enum aiReturn
|
||||
{
|
||||
//! Indicates that a function was successful
|
||||
AI_SUCCESS = 0x0,
|
||||
|
||||
//! Indicates that a function failed
|
||||
AI_FAILURE = -0x1,
|
||||
|
||||
//! Indicates that a file was invalid
|
||||
AI_INVALIDFILE = -0x2,
|
||||
|
||||
//! Indicates that not enough memory was available
|
||||
//! to perform the requested operation
|
||||
AI_OUTOFMEMORY = -0x3,
|
||||
|
||||
//! Indicates that an illegal argument has been
|
||||
//! passed to a function. This is rarely used,
|
||||
//! most functions assert in this case.
|
||||
|
@ -264,7 +298,6 @@ enum aiReturn
|
|||
* animations) of an import.
|
||||
* @see Importer::GetMemoryRequirements()
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct aiMemoryInfo
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
|
@ -276,6 +309,8 @@ struct aiMemoryInfo
|
|||
, meshes (0)
|
||||
, nodes (0)
|
||||
, animations (0)
|
||||
, cameras (0)
|
||||
, lights (0)
|
||||
, total (0)
|
||||
{}
|
||||
|
||||
|
@ -283,14 +318,25 @@ struct aiMemoryInfo
|
|||
|
||||
//! Storage allocated for texture data, in bytes
|
||||
unsigned int textures;
|
||||
|
||||
//! Storage allocated for material data, in bytes
|
||||
unsigned int materials;
|
||||
|
||||
//! Storage allocated for mesh data, in bytes
|
||||
unsigned int meshes;
|
||||
|
||||
//! Storage allocated for node data, in bytes
|
||||
unsigned int nodes;
|
||||
|
||||
//! Storage allocated for animation data, in bytes
|
||||
unsigned int animations;
|
||||
|
||||
//! Storage allocated for camera data, in bytes
|
||||
unsigned int cameras;
|
||||
|
||||
//! Storage allocated for light data, in bytes
|
||||
unsigned int lights;
|
||||
|
||||
//! Storage allocated for the import, in bytes
|
||||
unsigned int total;
|
||||
};
|
||||
|
@ -299,5 +345,12 @@ struct aiMemoryInfo
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //! __cplusplus
|
||||
|
||||
// Include implementations
|
||||
#include "aiVector3D.inl"
|
||||
#include "aiMatrix3x3.inl"
|
||||
#include "aiMatrix4x4.inl"
|
||||
|
||||
|
||||
#endif //!! include guard
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[i];
|
||||
switch (this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
case aiTextureType_DIFFUSE:
|
||||
if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture != piTexture)
|
||||
{
|
||||
pcMesh->piDiffuseTexture->Release();
|
||||
|
@ -257,7 +257,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
case aiTextureType_AMBIENT:
|
||||
if (pcMesh->piAmbientTexture && pcMesh->piAmbientTexture != piTexture)
|
||||
{
|
||||
pcMesh->piAmbientTexture->Release();
|
||||
|
@ -270,7 +270,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
case aiTextureType_SPECULAR:
|
||||
if (pcMesh->piSpecularTexture && pcMesh->piSpecularTexture != piTexture)
|
||||
{
|
||||
pcMesh->piSpecularTexture->Release();
|
||||
|
@ -283,7 +283,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
case aiTextureType_EMISSIVE:
|
||||
if (pcMesh->piEmissiveTexture && pcMesh->piEmissiveTexture != piTexture)
|
||||
{
|
||||
pcMesh->piEmissiveTexture->Release();
|
||||
|
@ -296,7 +296,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
case aiTextureType_SHININESS:
|
||||
if (pcMesh->piShininessTexture && pcMesh->piShininessTexture != piTexture)
|
||||
{
|
||||
pcMesh->piShininessTexture->Release();
|
||||
|
@ -309,8 +309,8 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
case aiTextureType_NORMALS:
|
||||
case aiTextureType_HEIGHT:
|
||||
if (pcMesh->piNormalTexture && pcMesh->piNormalTexture != piTexture)
|
||||
{
|
||||
pcMesh->piNormalTexture->Release();
|
||||
|
@ -325,7 +325,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
}
|
||||
}
|
||||
break;
|
||||
default: //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
|
||||
default: //case aiTextureType_OPACITY && case aiTextureType_OPACITY | 0x40000000:
|
||||
if (pcMesh->piOpacityTexture && pcMesh->piOpacityTexture != piTexture)
|
||||
{
|
||||
pcMesh->piOpacityTexture->Release();
|
||||
|
@ -340,42 +340,44 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// now update the material itself
|
||||
aiString szOld;
|
||||
const char* szKey = NULL;
|
||||
#if 0
|
||||
switch (this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
case aiTextureType_DIFFUSE:
|
||||
szKey = AI_MATKEY_TEXTURE_DIFFUSE(0);
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
case aiTextureType_AMBIENT:
|
||||
szKey = AI_MATKEY_TEXTURE_AMBIENT(0);
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
case aiTextureType_SPECULAR:
|
||||
szKey = AI_MATKEY_TEXTURE_SPECULAR(0);
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
case aiTextureType_EMISSIVE:
|
||||
szKey = AI_MATKEY_TEXTURE_EMISSIVE(0);
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
case aiTextureType_NORMALS:
|
||||
szKey = AI_MATKEY_TEXTURE_NORMALS(0);
|
||||
break;
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
case aiTextureType_HEIGHT:
|
||||
szKey = AI_MATKEY_TEXTURE_HEIGHT(0);
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
case aiTextureType_SHININESS:
|
||||
szKey = AI_MATKEY_TEXTURE_SHININESS(0);
|
||||
break;
|
||||
default: //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
|
||||
default: //case aiTextureType_OPACITY && case aiTextureType_OPACITY | 0x40000000:
|
||||
szKey = AI_MATKEY_TEXTURE_OPACITY(0);
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
ai_assert(NULL != szKey);
|
||||
|
||||
aiGetMaterialString(pcMat,szKey,&szOld);
|
||||
pcMat->AddProperty(&szString,szKey);
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType,0),&szOld);
|
||||
pcMat->AddProperty(&szString,AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType,0));
|
||||
|
||||
#if 0
|
||||
char szBuffer[512];
|
||||
sprintf(szBuffer,"%s%s",szKey,"_old");
|
||||
|
||||
|
@ -388,6 +390,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
|
|||
{
|
||||
pcMat->RemoveProperty(szBuffer);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
|
@ -426,31 +429,31 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType,
|
|||
IDirect3DTexture9** piTexture;
|
||||
switch (iType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
case aiTextureType_DIFFUSE:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
|
||||
szType = "Diffuse";
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
case aiTextureType_SPECULAR:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
|
||||
szType = "Specular";
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
case aiTextureType_AMBIENT:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
|
||||
szType = "Ambient";
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
case aiTextureType_EMISSIVE:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
|
||||
szType = "Emissive";
|
||||
break;
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
case aiTextureType_HEIGHT:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
|
||||
szType = "HeightMap";
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
case aiTextureType_NORMALS:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
|
||||
szType = "NormalMap";
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
case aiTextureType_SHININESS:
|
||||
piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
|
||||
szType = "Shininess";
|
||||
break;
|
||||
|
@ -578,8 +581,8 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
|
|||
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
||||
|
||||
// for each texture in the list ... add it
|
||||
// NOTE: This expects that AI_TEXTYPE_DIFFUSE is 7
|
||||
ai_assert(7 == AI_TEXTYPE_DIFFUSE);
|
||||
// NOTE: This expects that aiTextureType_DIFFUSE is 7
|
||||
ai_assert(7 == aiTextureType_DIFFUSE);
|
||||
unsigned int iUV;
|
||||
float fBlend;
|
||||
aiTextureOp eOp;
|
||||
|
@ -590,12 +593,12 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
|
|||
unsigned int iNum = 0;
|
||||
while (true)
|
||||
{
|
||||
if (AI_SUCCESS != aiGetMaterialTexture(pcMat,iNum,i,
|
||||
&szPath,&iUV,&fBlend,&eOp))
|
||||
if (AI_SUCCESS != aiGetMaterialTexture(pcMat,(aiTextureType)i,iNum,
|
||||
&szPath,NULL, &iUV,&fBlend,&eOp))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (AI_TEXTYPE_OPACITY == i)bNoOpacity = false;
|
||||
if (aiTextureType_OPACITY == i)bNoOpacity = false;
|
||||
AddTextureToDisplayList(i,iNum,&szPath,hTexture,iUV,fBlend,eOp,iMesh);
|
||||
++iNum;
|
||||
}
|
||||
|
@ -619,7 +622,7 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
|
|||
{
|
||||
// seems the diffuse texture contains alpha, therefore it has been
|
||||
// added to the opacity channel, too. Add a special value ...
|
||||
AddTextureToDisplayList(AI_TEXTYPE_OPACITY | 0x40000000,
|
||||
AddTextureToDisplayList(aiTextureType_OPACITY | 0x40000000,
|
||||
0,&szPath,hTexture,iUV,fBlend,eOp,iMesh);
|
||||
}
|
||||
}
|
||||
|
@ -967,7 +970,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
|
|||
ShowNormalUIComponents();
|
||||
}
|
||||
|
||||
if ((AI_TEXTYPE_OPACITY | 0x40000000) == pcNew->iType)
|
||||
if ((aiTextureType_OPACITY | 0x40000000) == pcNew->iType)
|
||||
{
|
||||
// for opacity textures display a warn message
|
||||
CLogDisplay::Instance().AddEntry("[INFO] This texture is not existing in the "
|
||||
|
@ -1204,7 +1207,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
|
|||
g_pcAsset->apcMeshes[i],"DIFFUSE_COLOR"));
|
||||
}
|
||||
}
|
||||
szMatKey = AI_MATKEY_COLOR_DIFFUSE;
|
||||
szMatKey = "$clr.diffuse";
|
||||
break;
|
||||
case ID_SOLONG_CLEARSPECULARCOLOR:
|
||||
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
|
||||
|
@ -1215,7 +1218,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
|
|||
g_pcAsset->apcMeshes[i],"SPECULAR_COLOR"));
|
||||
}
|
||||
}
|
||||
szMatKey = AI_MATKEY_COLOR_SPECULAR;
|
||||
szMatKey = "$clr.specular";
|
||||
break;
|
||||
case ID_SOLONG_CLEARAMBIENTCOLOR:
|
||||
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
|
||||
|
@ -1226,7 +1229,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
|
|||
g_pcAsset->apcMeshes[i],"AMBIENT_COLOR"));
|
||||
}
|
||||
}
|
||||
szMatKey = AI_MATKEY_COLOR_AMBIENT;
|
||||
szMatKey = "$clr.ambient";
|
||||
break;
|
||||
case ID_SOLONG_CLEAREMISSIVECOLOR:
|
||||
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
|
||||
|
@ -1237,7 +1240,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
|
|||
g_pcAsset->apcMeshes[i],"EMISSIVE_COLOR"));
|
||||
}
|
||||
}
|
||||
szMatKey = AI_MATKEY_COLOR_EMISSIVE;
|
||||
szMatKey = "$clr.emissive";
|
||||
break;
|
||||
default:
|
||||
|
||||
|
@ -1283,7 +1286,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
|
|||
// change the material key ...
|
||||
Assimp::MaterialHelper* pcMat = (Assimp::MaterialHelper*)g_pcAsset->pcScene->mMaterials[
|
||||
this->m_pcCurrentMaterial->iIndex];
|
||||
pcMat->AddProperty<aiColor4D>(&clrOld,1,szMatKey);
|
||||
pcMat->AddProperty<aiColor4D>(&clrOld,1,szMatKey,0,0);
|
||||
|
||||
if (ID_SOLONG_CLEARSPECULARCOLOR == LOWORD(wParam) &&
|
||||
aiShadingMode_Gouraud == apclrOut.front().pMesh->eShadingMode)
|
||||
|
@ -1420,35 +1423,35 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam)
|
|||
|
||||
switch (this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
case aiTextureType_DIFFUSE:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
case aiTextureType_SPECULAR:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SPECULAR(0));
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
case aiTextureType_AMBIENT:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_AMBIENT(0));
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
case aiTextureType_EMISSIVE:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_EMISSIVE(0));
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
case aiTextureType_NORMALS:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_NORMALS(0));
|
||||
break;
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
case aiTextureType_HEIGHT:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_HEIGHT(0));
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
case aiTextureType_SHININESS:
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SHININESS(0));
|
||||
break;
|
||||
case (AI_TEXTYPE_OPACITY | 0x40000000):
|
||||
case (aiTextureType_OPACITY | 0x40000000):
|
||||
|
||||
// set a special property to indicate that no alpha channel is required
|
||||
{int iVal = 1;
|
||||
pcMat->AddProperty<int>(&iVal,1,"no_a_from_d");}
|
||||
pcMat->AddProperty<int>(&iVal,1,"no_a_from_d",0,0);}
|
||||
|
||||
break;
|
||||
default: //case AI_TEXTYPE_OPACITY
|
||||
default: //case aiTextureType_OPACITY
|
||||
pcMat->RemoveProperty(AI_MATKEY_TEXTURE_OPACITY(0));
|
||||
};
|
||||
|
||||
|
@ -1505,41 +1508,42 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam)
|
|||
TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),this->m_hRoot,TVGN_CARET);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case ID_HEY_RESETTEXTURE:
|
||||
{
|
||||
aiString szOld;
|
||||
aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex];
|
||||
switch (this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
case AI_TEXTYPE_DIFFUSE:
|
||||
case aiTextureType_DIFFUSE:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_SPECULAR:
|
||||
case aiTextureType_SPECULAR:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SPECULAR(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_AMBIENT:
|
||||
case aiTextureType_AMBIENT:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_AMBIENT(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_EMISSIVE:
|
||||
case aiTextureType_EMISSIVE:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_EMISSIVE(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_NORMALS:
|
||||
case aiTextureType_NORMALS:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_NORMALS(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_HEIGHT:
|
||||
case aiTextureType_HEIGHT:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_HEIGHT(0) "_old",&szOld);
|
||||
break;
|
||||
case AI_TEXTYPE_SHININESS:
|
||||
case aiTextureType_SHININESS:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SHININESS(0) "_old",&szOld);
|
||||
break;
|
||||
default : //case AI_TEXTYPE_OPACITY && case AI_TEXTYPE_OPACITY | 0x40000000:
|
||||
default : //case aiTextureType_OPACITY && case aiTextureType_OPACITY | 0x40000000:
|
||||
aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_OPACITY(0) "_old",&szOld);
|
||||
break;
|
||||
};
|
||||
if (0 != szOld.length)this->ReplaceCurrentTexture(szOld.data);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2195,11 +2199,11 @@ int CDisplay::RenderTextureView()
|
|||
// commit the texture to the shader
|
||||
g_piPassThroughEffect->SetTexture("TEXTURE_2D",*this->m_pcCurrentTexture->piTexture);
|
||||
|
||||
if (AI_TEXTYPE_OPACITY == this->m_pcCurrentTexture->iType)
|
||||
if (aiTextureType_OPACITY == this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromR");
|
||||
}
|
||||
else if ((AI_TEXTYPE_OPACITY | 0x40000000) == this->m_pcCurrentTexture->iType)
|
||||
else if ((aiTextureType_OPACITY | 0x40000000) == this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA");
|
||||
}
|
||||
|
@ -2212,8 +2216,8 @@ int CDisplay::RenderTextureView()
|
|||
g_piPassThroughEffect->Begin(&dw,0);
|
||||
g_piPassThroughEffect->BeginPass(0);
|
||||
|
||||
if (AI_TEXTYPE_HEIGHT == this->m_pcCurrentTexture->iType ||
|
||||
AI_TEXTYPE_NORMALS == this->m_pcCurrentTexture->iType)
|
||||
if (aiTextureType_HEIGHT == this->m_pcCurrentTexture->iType ||
|
||||
aiTextureType_NORMALS == this->m_pcCurrentTexture->iType)
|
||||
{
|
||||
// manually disable alpha blending
|
||||
g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
|
||||
|
|
|
@ -786,6 +786,9 @@ int CMaterialManager::CreateMaterial(
|
|||
|
||||
aiString szPath;
|
||||
|
||||
aiTextureMapMode mapU(aiTextureMapMode_Wrap),mapV(aiTextureMapMode_Wrap);
|
||||
|
||||
bool bib =false;
|
||||
if (pcSource->mTextureCoords[0])
|
||||
{
|
||||
|
||||
|
@ -795,6 +798,9 @@ int CMaterialManager::CreateMaterial(
|
|||
if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0),&szPath))
|
||||
{
|
||||
LoadTexture(&pcMesh->piDiffuseTexture,&szPath);
|
||||
|
||||
aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU);
|
||||
aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV);
|
||||
}
|
||||
|
||||
if (pcSource->mTextureCoords[1])
|
||||
|
@ -833,7 +839,7 @@ int CMaterialManager::CreateMaterial(
|
|||
|
||||
// NOTE: This special value is set by the tree view if the user
|
||||
// manually removes the alpha texture from the view ...
|
||||
if (AI_SUCCESS != aiGetMaterialInteger(pcMat,"no_a_from_d",&iVal))
|
||||
if (AI_SUCCESS != aiGetMaterialInteger(pcMat,"no_a_from_d",0,0,&iVal))
|
||||
{
|
||||
pcMesh->piOpacityTexture = pcMesh->piDiffuseTexture;
|
||||
pcMesh->piOpacityTexture->AddRef();
|
||||
|
@ -879,6 +885,7 @@ int CMaterialManager::CreateMaterial(
|
|||
{
|
||||
LoadTexture(&pcMesh->piNormalTexture,&szPath);
|
||||
}
|
||||
else bib = true;
|
||||
bHM = true;
|
||||
}
|
||||
|
||||
|
@ -968,6 +975,28 @@ int CMaterialManager::CreateMaterial(
|
|||
sMacro[iCurrent].Name = "AV_DIFFUSE_TEXTURE";
|
||||
sMacro[iCurrent].Definition = "1";
|
||||
++iCurrent;
|
||||
|
||||
if (mapU == aiTextureMapMode_Wrap)
|
||||
sMacro[iCurrent].Name = "AV_WRAPU";
|
||||
else if (mapU == aiTextureMapMode_Mirror)
|
||||
sMacro[iCurrent].Name = "AV_MIRRORU";
|
||||
else // if (mapU == aiTextureMapMode_Clamp)
|
||||
sMacro[iCurrent].Name = "AV_CLAMPU";
|
||||
|
||||
sMacro[iCurrent].Definition = "1";
|
||||
++iCurrent;
|
||||
|
||||
|
||||
|
||||
if (mapV == aiTextureMapMode_Wrap)
|
||||
sMacro[iCurrent].Name = "AV_WRAPV";
|
||||
else if (mapV == aiTextureMapMode_Mirror)
|
||||
sMacro[iCurrent].Name = "AV_MIRRORV";
|
||||
else // if (mapV == aiTextureMapMode_Clamp)
|
||||
sMacro[iCurrent].Name = "AV_CLAMPV";
|
||||
|
||||
sMacro[iCurrent].Definition = "1";
|
||||
++iCurrent;
|
||||
}
|
||||
if (pcMesh->piDiffuseTexture2)
|
||||
{
|
||||
|
@ -993,7 +1022,7 @@ int CMaterialManager::CreateMaterial(
|
|||
sMacro[iCurrent].Definition = "1";
|
||||
++iCurrent;
|
||||
}
|
||||
if (pcMesh->piNormalTexture)
|
||||
if (pcMesh->piNormalTexture && !bib)
|
||||
{
|
||||
sMacro[iCurrent].Name = "AV_NORMAL_TEXTURE";
|
||||
sMacro[iCurrent].Definition = "1";
|
||||
|
|
|
@ -530,6 +530,24 @@ std::string g_szMaterialShader = std::string(
|
|||
"sampler DIFFUSE_SAMPLER\n"
|
||||
"{\n"
|
||||
"Texture = <DIFFUSE_TEXTURE>;\n"
|
||||
"#ifdef AV_WRAPU\n"
|
||||
"AddressU = WRAP;\n"
|
||||
"#endif\n"
|
||||
"#ifdef AV_MIRRORU\n"
|
||||
"AddressU = MIRROR;\n"
|
||||
"#endif\n"
|
||||
"#ifdef AV_CLAMPU\n"
|
||||
"AddressU = CLAMP;\n"
|
||||
"#endif\n"
|
||||
"#ifdef AV_WRAPV\n"
|
||||
"AddressV = WRAP;\n"
|
||||
"#endif\n"
|
||||
"#ifdef AV_MIRRORV\n"
|
||||
"AddressV = MIRROR;\n"
|
||||
"#endif\n"
|
||||
"#ifdef AV_CLAMPV\n"
|
||||
"AddressV = CLAMP;\n"
|
||||
"#endif\n"
|
||||
"MinFilter=LINEAR;\n"
|
||||
"MagFilter=LINEAR;\n"
|
||||
"MipFilter=LINEAR;\n"
|
||||
|
|
|
@ -140,7 +140,8 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
|||
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
|
||||
aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality
|
||||
| aiProcess_RemoveRedundantMaterials | aiProcess_SortByPType |
|
||||
aiProcess_FindDegenerates | aiProcess_FindInvalidData); // validate the output data structure
|
||||
aiProcess_FindDegenerates | aiProcess_FindInvalidData |
|
||||
aiProcess_GenUVCoords | aiProcess_TransformUVCoords ); // validate the output data structure
|
||||
|
||||
// get the end time of zje operation, calculate delta t
|
||||
double fEnd = (double)timeGetTime();
|
||||
|
|
|
@ -726,6 +726,10 @@
|
|||
RelativePath="..\..\include\BoostWorkaround\boost\format.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\BoostWorkaround\boost\scoped_array.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\BoostWorkaround\boost\scoped_ptr.hpp"
|
||||
>
|
||||
|
@ -903,14 +907,6 @@
|
|||
RelativePath="..\..\code\TargetAnimation.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\TextureTransform.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\TextureTransform.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
|
||||
>
|
||||
|
@ -1344,6 +1340,14 @@
|
|||
<File
|
||||
RelativePath="..\..\code\ACLoader.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ACLoader.h"
|
||||
|
@ -1454,6 +1458,14 @@
|
|||
RelativePath="..\..\code\CalcTangentsProcess.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ComputeUVMappingProcess.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ComputeUVMappingProcess.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ConvertToLHProcess.cpp"
|
||||
>
|
||||
|
@ -1574,6 +1586,14 @@
|
|||
RelativePath="..\..\code\SplitLargeMeshes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\TextureTransform.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\TextureTransform.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\TriangulateProcess.cpp"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue