Minor changes to the logger (was necessary for the integration of jAssimp)

Fixed face winding bugs (cw now ...)
jAssimp incremental Update
3DS hierarchy bug fixed
Added "MakeVerboseFormat" postprocess step
Viewer bugfixes

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@41 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-05-25 22:29:05 +00:00
parent 522ce03d00
commit 0d728ce17b
46 changed files with 2242 additions and 334 deletions

View File

@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the 3ds importer class */ /** @file Implementation of the 3ds importer class */
#include "3DSLoader.h" #include "3DSLoader.h"
#include "MaterialSystem.h" #include "MaterialSystem.h"
#include "DefaultLogger.h"
#include "../include/IOStream.h" #include "../include/IOStream.h"
#include "../include/IOSystem.h" #include "../include/IOSystem.h"
@ -98,11 +99,18 @@ void Dot3DSImporter::ReplaceDefaultMaterial()
{ {
// NOTE: The additional check seems to be necessary, // NOTE: The additional check seems to be necessary,
// some exporters seem to generate invalid data here // some exporters seem to generate invalid data here
if (0xcdcdcdcd == (*a) || (*a) >= this->mScene->mMaterials.size()) if (0xcdcdcdcd == (*a))
{ {
(*a) = iIndex; (*a) = iIndex;
++iCnt; ++iCnt;
} }
else if ( (*a) >= this->mScene->mMaterials.size())
{
(*a) = iIndex;
++iCnt;
DefaultLogger::get()->warn("Material index overflow in 3DS file. Assigning "
"default material ...");
}
} }
} }
if (0 != iCnt && iIndex == this->mScene->mMaterials.size()) if (0 != iCnt && iIndex == this->mScene->mMaterials.size())
@ -125,14 +133,17 @@ void Dot3DSImporter::CheckIndices(Dot3DS::Mesh* sMesh)
// check whether all indices are in range // check whether all indices are in range
if ((*i).i1 >= sMesh->mPositions.size()) if ((*i).i1 >= sMesh->mPositions.size())
{ {
DefaultLogger::get()->warn("Face index overflow in 3DS file (#1)");
(*i).i1 = sMesh->mPositions.size()-1; (*i).i1 = sMesh->mPositions.size()-1;
} }
if ((*i).i2 >= sMesh->mPositions.size()) if ((*i).i2 >= sMesh->mPositions.size())
{ {
DefaultLogger::get()->warn("Face index overflow in 3DS file (#2)");
(*i).i2 = sMesh->mPositions.size()-1; (*i).i2 = sMesh->mPositions.size()-1;
} }
if ((*i).i3 >= sMesh->mPositions.size()) if ((*i).i3 >= sMesh->mPositions.size())
{ {
DefaultLogger::get()->warn("Face index overflow in 3DS file (#3)");
(*i).i3 = sMesh->mPositions.size()-1; (*i).i3 = sMesh->mPositions.size()-1;
} }
} }
@ -155,31 +166,55 @@ void Dot3DSImporter::MakeUnique(Dot3DS::Mesh* sMesh)
vNew2.resize(sMesh->mFaces.size() * 3); vNew2.resize(sMesh->mFaces.size() * 3);
for (unsigned int i = 0; i < sMesh->mFaces.size();++i) for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
{ {
uint32_t iTemp1,iTemp2;
// position and texture coordinates // position and texture coordinates
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1]; vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1]; vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3];
sMesh->mFaces[i].i1 = iBase++; iTemp1 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2]; vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i2]; vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i2];
sMesh->mFaces[i].i2 = iBase++; iTemp2 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3]; vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3]; vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1];
sMesh->mFaces[i].i3 = iBase++; sMesh->mFaces[i].i3 = iBase++;
sMesh->mFaces[i].i1 = iTemp1;
sMesh->mFaces[i].i2 = iTemp2;
// handle the face order ...
/*if (iTemp1 > iTemp2)
{
sMesh->mFaces[i].bFlipped = true;
}*/
} }
} }
else else
{ {
for (unsigned int i = 0; i < sMesh->mFaces.size();++i) for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
{ {
uint32_t iTemp1,iTemp2;
// position only // position only
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
sMesh->mFaces[i].i1 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
sMesh->mFaces[i].i2 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3]; vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
iTemp1 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
iTemp2 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
sMesh->mFaces[i].i3 = iBase++; sMesh->mFaces[i].i3 = iBase++;
sMesh->mFaces[i].i1 = iTemp1;
sMesh->mFaces[i].i2 = iTemp2;
// handle the face order ...
/*if (iTemp1 > iTemp2)
{
sMesh->mFaces[i].bFlipped = true;
}*/
} }
} }
sMesh->mPositions = vNew; sMesh->mPositions = vNew;
@ -216,9 +251,16 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
// phong shininess and shininess strength
if (Dot3DS::Dot3DSFile::Phong == oldMat.mShading ||
Dot3DS::Dot3DSFile::Metal == oldMat.mShading)
{
mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
}
// opacity // opacity
mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY); mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
@ -231,8 +273,6 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
{ {
case Dot3DS::Dot3DSFile::Flat: case Dot3DS::Dot3DSFile::Flat:
eShading = aiShadingMode_Flat; break; eShading = aiShadingMode_Flat; break;
case Dot3DS::Dot3DSFile::Phong :
eShading = aiShadingMode_Phong; break;
// I don't know what "Wire" shading should be, // 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 (L dot N) shading
@ -243,6 +283,9 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
// assume cook-torrance shading for metals. // assume cook-torrance shading for metals.
// NOTE: I assume the real shader inside 3ds max is an anisotropic // NOTE: I assume the real shader inside 3ds max is an anisotropic
// Phong-Blinn shader, but this is a good approximation too // Phong-Blinn shader, but this is a good approximation too
case Dot3DS::Dot3DSFile::Phong :
eShading = aiShadingMode_Phong; break;
case Dot3DS::Dot3DSFile::Metal : case Dot3DS::Dot3DSFile::Metal :
eShading = aiShadingMode_CookTorrance; break; eShading = aiShadingMode_CookTorrance; break;
} }
@ -361,9 +404,8 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
else aiSplit[*a].push_back(iNum); else aiSplit[*a].push_back(iNum);
} }
// now generate submeshes // now generate submeshes
#if 0
bool bFirst = true; bool bFirst = true;
#endif
for (unsigned int p = 0; p < this->mScene->mMaterials.size();++p) for (unsigned int p = 0; p < this->mScene->mMaterials.size();++p)
{ {
if (aiSplit[p].size() != 0) if (aiSplit[p].size() != 0)
@ -377,7 +419,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName); p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName);
avOutMeshes.push_back(p_pcOut); avOutMeshes.push_back(p_pcOut);
#if 0
if (bFirst) if (bFirst)
{ {
p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4(); p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4();
@ -385,7 +427,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
*((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat; *((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat;
bFirst = false; bFirst = false;
} }
#endif
// convert vertices // convert vertices
p_pcOut->mNumVertices = aiSplit[p].size()*3; p_pcOut->mNumVertices = aiSplit[p].size()*3;
@ -408,7 +450,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
p_pcOut->mFaces[q].mIndices = new unsigned int[3]; p_pcOut->mFaces[q].mIndices = new unsigned int[3];
p_pcOut->mFaces[q].mNumIndices = 3; p_pcOut->mFaces[q].mNumIndices = 3;
p_pcOut->mFaces[q].mIndices[0] = iBase; p_pcOut->mFaces[q].mIndices[2] = iBase;
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i1]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i1];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i1]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i1];
@ -416,7 +458,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i2]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i2];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i2]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i2];
p_pcOut->mFaces[q].mIndices[2] = iBase; p_pcOut->mFaces[q].mIndices[0] = iBase;
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i3]; p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i3];
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i3]; p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i3];
} }
@ -505,7 +547,7 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
for (unsigned int i = 0;i < iArray.size();++i) for (unsigned int i = 0;i < iArray.size();++i)
{ {
const unsigned int iIndex = iArray[i]; const unsigned int iIndex = iArray[i];
#if 0
if (NULL != pcSOut->mMeshes[iIndex]->mColors[1]) if (NULL != pcSOut->mMeshes[iIndex]->mColors[1])
{ {
pcOut->mTransformation = *((aiMatrix4x4*) pcOut->mTransformation = *((aiMatrix4x4*)
@ -514,13 +556,11 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1]; delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1];
pcSOut->mMeshes[iIndex]->mColors[1] = NULL; pcSOut->mMeshes[iIndex]->mColors[1] = NULL;
} }
#endif
pcOut->mMeshes[i] = iIndex; pcOut->mMeshes[i] = iIndex;
} }
// NOTE: Not necessary. We can use the given transformation matrix. // (code for keyframe animation. however, this is currently not supported by Assimp)
// However, we'd need it if we wanted to implement keyframe animation
#if 0 #if 0
// build the scaling matrix. Toggle y and z axis // build the scaling matrix. Toggle y and z axis
aiMatrix4x4 mS; aiMatrix4x4 mS;
@ -536,11 +576,34 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
// build the pivot matrix. Toggle y and z axis // build the pivot matrix. Toggle y and z axis
aiMatrix4x4 mP; aiMatrix4x4 mP;
mP.a4 = pcIn->vPivot.x; mP.a4 = -pcIn->vPivot.x;
mP.b4 = pcIn->vPivot.z; mP.b4 = -pcIn->vPivot.z;
mP.c4 = pcIn->vPivot.y; mP.c4 = -pcIn->vPivot.y;
#endif
// build a matrix to flip the z coordinate of the vertices
aiMatrix4x4 mF;
mF.c3 = -1.0f;
// build the final matrix
// NOTE: This should be the identity. Theoretically. In reality
// there are many models with very funny local matrices and
// very different keyframe values ... this is the only reason
// why we extract the data from the first keyframe.
pcOut->mTransformation = mF; /* mF * mT * pcIn->mRotation * mS * mP *
pcOut->mTransformation.Inverse(); */
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0
if (pcOut->mTransformation != mF)
{
DefaultLogger::get()->warn("The local transformation matrix of the "
"3ds file does not match the first keyframe. Using the "
"information from the keyframe.");
}
#endif #endif
pcOut->mTransformation = aiMatrix4x4(); // mT * pcIn->mRotation * mS * mP * pcOut->mTransformation.Inverse();
pcOut->mNumChildren = pcIn->mChildren.size(); pcOut->mNumChildren = pcIn->mChildren.size();
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()]; pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
@ -748,6 +811,10 @@ void Dot3DSImporter::BakeScaleNOffset(
{ {
(*a)->iUVSrc = 0; (*a)->iUVSrc = 0;
} }
DefaultLogger::get()->error("There are too many "
"combinations of different UV scaling/offset/rotation operations "
"to generate an UV channel for each (maximum is 4). Using the "
"first UV channel ...");
continue; continue;
} }
const aiVector3D* pvBase = _pvBase; const aiVector3D* pvBase = _pvBase;
@ -815,6 +882,9 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
// //
unsigned int iCnt = 0; unsigned int iCnt = 0;
DefaultLogger::get()->warn("No hierarchy information has been "
"found in the file. A flat hierarchy tree is built ...");
pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes; pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes;
pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mNumMeshes ]; pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mNumMeshes ];
@ -827,7 +897,12 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
pcNode->mMeshes = new unsigned int[1]; pcNode->mMeshes = new unsigned int[1];
pcNode->mMeshes[0] = i; pcNode->mMeshes[0] = i;
pcNode->mNumMeshes = 1; pcNode->mNumMeshes = 1;
pcNode->mName.Set("UNNAMED");
std::string s;
std::stringstream ss(s);
ss << "UNNAMED[" << i << + "]";
pcNode->mName.Set(s);
// add the new child to the parent node // add the new child to the parent node
pcOut->mRootNode->mChildren[i] = pcNode; pcOut->mRootNode->mChildren[i] = pcNode;
@ -860,6 +935,7 @@ void Dot3DSImporter::ConvertScene(aiScene* pcOut)
this->ConvertMeshes(pcOut); this->ConvertMeshes(pcOut);
return; return;
} }
#if 0
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture, void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
const std::vector<aiVector2D>& p_vIn, const std::vector<aiVector2D>& p_vIn,
@ -887,3 +963,4 @@ void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
} }
return; return;
} }
#endif

View File

@ -59,7 +59,7 @@ void Dot3DSImporter::GenNormals(Dot3DS::Mesh* sMesh)
sMesh->mNormals.resize(sMesh->mPositions.size(),aiVector3D()); sMesh->mNormals.resize(sMesh->mPositions.size(),aiVector3D());
for( unsigned int a = 0; a < sMesh->mFaces.size(); a++) for( unsigned int a = 0; a < sMesh->mFaces.size(); a++)
{ {
const Dot3DS::Face& face = sMesh->mFaces[a]; Dot3DS::Face& face = sMesh->mFaces[a];
// assume it is a triangle // assume it is a triangle
aiVector3D* pV1 = &sMesh->mPositions[face.i1]; aiVector3D* pV1 = &sMesh->mPositions[face.i1];

View File

@ -199,6 +199,7 @@ public:
// Specifies the shininess of the material // Specifies the shininess of the material
// followed by percentage chunk // followed by percentage chunk
CHUNK_MAT_SHININESS = 0xA040, CHUNK_MAT_SHININESS = 0xA040,
CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
// Specifies the shading mode to be used // Specifies the shading mode to be used
// followed by a short // followed by a short
@ -304,7 +305,7 @@ public:
/** Helper structure representing a 3ds mesh face */ /** Helper structure representing a 3ds mesh face */
struct Face struct Face
{ {
Face() : iSmoothGroup(0), bDirection(true), i1(0), i2(0), i3(0) Face() : iSmoothGroup(0), i1(0), i2(0), i3(0), bFlipped(false)
{ {
// let the rest uninitialized for performance // let the rest uninitialized for performance
} }
@ -327,9 +328,8 @@ struct Face
//! specifies to which smoothing group the face belongs to //! specifies to which smoothing group the face belongs to
uint32_t iSmoothGroup; uint32_t iSmoothGroup;
//! Direction the normal vector of the face //! Specifies that the face normal must be flipped
//! will be pointing to bool bFlipped;
bool bDirection;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a texture */ /** Helper structure representing a texture */
@ -376,7 +376,8 @@ struct Material
mTransparency (1.0f), mTransparency (1.0f),
mBumpHeight (1.0f), mBumpHeight (1.0f),
iBakeUVTransform (0), iBakeUVTransform (0),
pcSingleTexture (NULL) pcSingleTexture (NULL),
mShininessStrength (1.0f)
{ {
static int iCnt = 0; static int iCnt = 0;
std::stringstream ss(mName); std::stringstream ss(mName);
@ -389,6 +390,8 @@ struct Material
aiColor3D mDiffuse; aiColor3D mDiffuse;
//! Specular exponent //! Specular exponent
float mSpecularExponent; float mSpecularExponent;
//! Shininess strength, in percent
float mShininessStrength;
//! Specular color of the material //! Specular color of the material
aiColor3D mSpecular; aiColor3D mSpecular;
//! Ambient color of the material //! Ambient color of the material
@ -462,9 +465,12 @@ struct Mesh
struct Node struct Node
{ {
Node() Node()
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0 #if 0
: vScaling(1.0f,1.0f,1.0f) : vScaling(1.0f,1.0f,1.0f)
#endif #endif
{ {
static int iCnt = 0; static int iCnt = 0;
std::stringstream ss(mName); std::stringstream ss(mName);
@ -489,6 +495,7 @@ struct Node
//! Index of the node //! Index of the node
int16_t mHierarchyIndex; int16_t mHierarchyIndex;
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0 #if 0
aiVector3D vPivot; aiVector3D vPivot;
aiVector3D vScaling; aiVector3D vScaling;
@ -502,7 +509,7 @@ struct Node
{ {
mChildren.push_back(pc); mChildren.push_back(pc);
pc->mParent = this; pc->mParent = this;
pc->mHierarchyPos = this->mHierarchyPos+1; //pc->mHierarchyPos = this->mHierarchyPos+1;
return *this; return *this;
} }
}; };

View File

@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the 3ds importer class */ /** @file Implementation of the 3ds importer class */
#include "3DSLoader.h" #include "3DSLoader.h"
#include "MaterialSystem.h" #include "MaterialSystem.h"
#include "DefaultLogger.h"
#include "../include/IOStream.h" #include "../include/IOStream.h"
#include "../include/IOSystem.h" #include "../include/IOSystem.h"
@ -59,7 +60,6 @@ using namespace Assimp;
"specified in the higher-level chunk header." \ "specified in the higher-level chunk header." \
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
Dot3DSImporter::Dot3DSImporter() Dot3DSImporter::Dot3DSImporter()
@ -145,6 +145,7 @@ void Dot3DSImporter::InternReadFile(
this->mMasterScale = 1.0f; this->mMasterScale = 1.0f;
this->mBackgroundImage = ""; this->mBackgroundImage = "";
this->bHasBG = false; this->bHasBG = false;
this->mErrorText = "";
int iRemaining = (unsigned int)fileSize; int iRemaining = (unsigned int)fileSize;
this->ParseMainChunk(&iRemaining); this->ParseMainChunk(&iRemaining);
@ -171,30 +172,9 @@ void Dot3DSImporter::InternReadFile(
// found in the file // found in the file
this->ReplaceDefaultMaterial(); this->ReplaceDefaultMaterial();
try // Convert the scene from our internal representation to an aiScene object
{ this->ConvertScene(pScene);
// Convert the scene from our internal representation to an aiScene object
this->ConvertScene(pScene);
}
catch (ImportErrorException ex)
{
// delete the scene itself
if (pScene->mMeshes)
{
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
delete pScene->mMeshes[i];
delete[] pScene->mMeshes;
}
if (pScene->mMaterials)
{
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
delete pScene->mMaterials[i];
delete[] pScene->mMaterials;
}
// there are no animations
if (pScene->mRootNode)DeleteNodeRecursively(pScene->mRootNode);
throw ex;
}
// Generate the node graph for the scene. This is a little bit // Generate the node graph for the scene. This is a little bit
// tricky since we'll need to split some meshes into submeshes // tricky since we'll need to split some meshes into submeshes
@ -205,6 +185,12 @@ void Dot3DSImporter::InternReadFile(
delete[] this->mBuffer; delete[] this->mBuffer;
delete this->mScene; delete this->mScene;
// check whether an error occured during reading ... set it as warning
if ("" != this->mErrorText)
{
DefaultLogger::get()->warn(this->mErrorText);
}
return; return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -532,7 +518,7 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
const unsigned char* sz = (unsigned char*)this->mCurrent; const unsigned char* sz = (unsigned char*)this->mCurrent;
unsigned int iCnt = 0; unsigned int iCnt = 0;
uint16_t iHierarchy; uint16_t iHierarchy;
//uint16_t iTemp; // uint16_t iTemp;
Dot3DS::Node* pcNode; Dot3DS::Node* pcNode;
switch (psChunk->Flag) switch (psChunk->Flag)
{ {
@ -554,20 +540,28 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
iHierarchy++; iHierarchy++;
pcNode->mHierarchyPos = iHierarchy; pcNode->mHierarchyPos = iHierarchy;
pcNode->mHierarchyIndex = this->mLastNodeIndex; pcNode->mHierarchyIndex = this->mLastNodeIndex;
if (iHierarchy > this->mLastNodeIndex) if (this->mCurrentNode && this->mCurrentNode->mHierarchyPos == iHierarchy)
{
// add to the parent of the last touched node
this->mCurrentNode->mParent->push_back(pcNode);
this->mLastNodeIndex++;
}
else if(iHierarchy >= this->mLastNodeIndex)
{ {
// place it at the current position in the hierarchy // place it at the current position in the hierarchy
this->mCurrentNode->push_back(pcNode); this->mCurrentNode->push_back(pcNode);
this->mLastNodeIndex = iHierarchy;
} }
else else
{ {
// need to go back to the specified position in the hierarchy. // need to go back to the specified position in the hierarchy.
this->InverseNodeSearch(pcNode,this->mCurrentNode); this->InverseNodeSearch(pcNode,this->mCurrentNode);
this->mLastNodeIndex++;
} }
this->mLastNodeIndex++;
this->mCurrentNode = pcNode; this->mCurrentNode = pcNode;
break; break;
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0 #if 0
case Dot3DSFile::CHUNK_TRACKPIVOT: case Dot3DSFile::CHUNK_TRACKPIVOT:
@ -651,42 +645,33 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
if (0.0f != fRadians) if (0.0f != fRadians)
{ {
// if the radians go beyond PI then the rotations
// thereafter must be inversed
#if 0
if (neg)fRadians *= -1.0f;
if ((fRadians >= 3.1415926f || fRadians <= -3.1415926f))
{
neg = !neg;
}
#endif
// get the rotation matrix around the axis // get the rotation matrix around the axis
const float fSin = sinf(-fRadians); const float fSin = sinf(-fRadians);
const float fCos = cosf(-fRadians); const float fCos = cosf(-fRadians);
const float fOneMinusCos = 1.0f - fCos; const float fOneMinusCos = 1.0f - fCos;
std::swap(vAxis.z,vAxis.y); std::swap(vAxis.z,vAxis.y);
vAxis.Normalize(); //vAxis.z *= -1.0f;
//vAxis.Normalize();
aiMatrix4x4 mRot = aiMatrix4x4( aiMatrix4x4 mRot = aiMatrix4x4(
(vAxis.x * vAxis.x) * fOneMinusCos + fCos, (vAxis.x * vAxis.x) * fOneMinusCos + fCos,
(vAxis.x * vAxis.y) * fOneMinusCos - (vAxis.z * fSin), (vAxis.x * vAxis.y) * fOneMinusCos /*-*/- (vAxis.z * fSin),
(vAxis.x * vAxis.z) * fOneMinusCos + (vAxis.y * fSin), (vAxis.x * vAxis.z) * fOneMinusCos /*+*/+ (vAxis.y * fSin),
0.0f, 0.0f,
(vAxis.y * vAxis.x) * fOneMinusCos + (vAxis.z * fSin), (vAxis.y * vAxis.x) * fOneMinusCos /*+*/+ (vAxis.z * fSin),
(vAxis.y * vAxis.y) * fOneMinusCos + fCos, (vAxis.y * vAxis.y) * fOneMinusCos + fCos,
(vAxis.y * vAxis.z) * fOneMinusCos - (vAxis.x * fSin), (vAxis.y * vAxis.z) * fOneMinusCos /*-*/- (vAxis.x * fSin),
0.0f, 0.0f,
(vAxis.z * vAxis.x) * fOneMinusCos - (vAxis.y * fSin), (vAxis.z * vAxis.x) * fOneMinusCos /*-*/- (vAxis.y * fSin),
(vAxis.z * vAxis.y) * fOneMinusCos + (vAxis.x * fSin), (vAxis.z * vAxis.y) * fOneMinusCos /*+*/+ (vAxis.x * fSin),
(vAxis.z * vAxis.z) * fOneMinusCos + fCos, (vAxis.z * vAxis.z) * fOneMinusCos + fCos,
0.0f,0.0f,0.0f,0.0f,1.0f); 0.0f,0.0f,0.0f,0.0f,1.0f);
//mRot.Transpose(); mRot.Transpose();
// build a chain of concatenated rotation matrix' // build a chain of concatenated rotation matrix'
// if there are multiple track chunks for the same frame // if there are multiple track chunks for the same frame
// (there are some silly files usinf this ...)
if (0 != iNum0) if (0 != iNum0)
{ {
this->mCurrentNode->mRotation = this->mCurrentNode->mRotation * mRot; this->mCurrentNode->mRotation = this->mCurrentNode->mRotation * mRot;
@ -739,14 +724,19 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
this->mCurrentNode->vScaling.y *= vMe.y; this->mCurrentNode->vScaling.y *= vMe.y;
this->mCurrentNode->vScaling.z *= vMe.z; this->mCurrentNode->vScaling.z *= vMe.z;
} }
else
{
DefaultLogger::get()->warn("Found zero scaling factors. "
"This will be ignored.");
}
this->mCurrent += sizeof(aiVector3D); this->mCurrent += sizeof(aiVector3D);
} }
else this->mCurrent += sizeof(uint32_t) + sizeof(aiVector3D); else this->mCurrent += sizeof(uint32_t) + sizeof(aiVector3D);
} }
} }
break; break;
#endif // end keyframe animation code
#endif // 0
}; };
if ((unsigned int)pcCurNext < (unsigned int)this->mCurrent) if ((unsigned int)pcCurNext < (unsigned int)this->mCurrent)
{ {
@ -790,13 +780,6 @@ void Dot3DSImporter::ParseFaceChunk(int* piRemaining)
{ {
// nth bit is set for nth smoothing group // nth bit is set for nth smoothing group
(*i).iSmoothGroup = *((uint32_t*)this->mCurrent); (*i).iSmoothGroup = *((uint32_t*)this->mCurrent);
#if 0
for (unsigned int x = 0, a = 1; x < 32;++x,a <<= 1)
{
if ((*i).iSmoothGroup & a)
mMesh.bSmoothGroupRequired[x] = true;
}
#endif
this->mCurrent += sizeof(uint32_t); this->mCurrent += sizeof(uint32_t);
} }
break; break;
@ -955,10 +938,10 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
aiMatrix4x4 mMe = mMesh.mMat; aiMatrix4x4 mMe = mMesh.mMat;
mMe.a1 *= -1.0f; mMe.a1 *= -1.0f;
mMe.a2 *= -1.0f; mMe.b1 *= -1.0f;
mMe.a3 *= -1.0f; mMe.c1 *= -1.0f;
mMe.a4 *= -1.0f; mMe.d1 *= -1.0f;
mInv = mMe * mInv; mInv = mInv * mMe;
for (register unsigned int i = 0; i < mMesh.mPositions.size();++i) for (register unsigned int i = 0; i < mMesh.mPositions.size();++i)
{ {
aiVector3D a,c; aiVector3D a,c;
@ -1007,8 +990,6 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
sFace.i3 = *((uint16_t*)this->mCurrent); sFace.i3 = *((uint16_t*)this->mCurrent);
this->mCurrent += 2*sizeof(uint16_t); this->mCurrent += 2*sizeof(uint16_t);
mMesh.mFaces.push_back(sFace); mMesh.mFaces.push_back(sFace);
//if (sFace.i1 < sFace.i2)sFace.bDirection = false;
} }
// resize the material array (0xcdcdcdcd marks the // resize the material array (0xcdcdcdcd marks the
@ -1131,6 +1112,14 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining)
else *pcf *= (float)0xFFFF; else *pcf *= (float)0xFFFF;
break; break;
case Dot3DSFile::CHUNK_MAT_SHININESS_PERCENT:
pcf = &this->mScene->mMaterials.back().mShininessStrength;
*pcf = this->ParsePercentageChunk();
if (is_qnan(*pcf))
*pcf = 0.0f;
else *pcf *= (float)0xffff / 100.0f;
break;
case Dot3DSFile::CHUNK_MAT_SELF_ILPCT: case Dot3DSFile::CHUNK_MAT_SELF_ILPCT:
pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend; pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend;
*pcf = this->ParsePercentageChunk(); *pcf = this->ParsePercentageChunk();

View File

@ -507,10 +507,12 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
for (unsigned int t = 0; t < 3;++t) for (unsigned int t = 0; t < 3;++t)
{ {
p_pcOut->mFaces[q].mIndices[t] = iBase;
p_pcOut->mVertices[iBase] = mesh.mPositions[mesh.mFaces[iIndex].mIndices[t]]; p_pcOut->mVertices[iBase] = mesh.mPositions[mesh.mFaces[iIndex].mIndices[t]];
p_pcOut->mNormals[iBase++] = mesh.mNormals[mesh.mFaces[iIndex].mIndices[t]]; p_pcOut->mNormals[iBase++] = mesh.mNormals[mesh.mFaces[iIndex].mIndices[t]];
} }
p_pcOut->mFaces[q].mIndices[0] = iBase-2;
p_pcOut->mFaces[q].mIndices[1] = iBase-1;
p_pcOut->mFaces[q].mIndices[2] = iBase;
} }
} }
// convert texture coordinates // convert texture coordinates

View File

@ -81,24 +81,39 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("CalcTangentsProcess begin"); DefaultLogger::get()->debug("CalcTangentsProcess begin");
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
ProcessMesh( pScene->mMeshes[a]); if(ProcessMesh( pScene->mMeshes[a]))bHas = true;
DefaultLogger::get()->debug("CalcTangentsProcess finished"); if (bHas)DefaultLogger::get()->debug("CalcTangentsProcess finished. There was much work to do ...");
else DefaultLogger::get()->debug("CalcTangentsProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Calculates tangents and bitangents for the given mesh // Calculates tangents and bitangents for the given mesh
void CalcTangentsProcess::ProcessMesh( aiMesh* pMesh) bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
{ {
// we assume that the mesh is still in the verbose vertex format where each face has its own set // we assume that the mesh is still in the verbose vertex format where each face has its own set
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
// assert() it here. // assert() it here.
//assert( must be verbose, dammit); //assert( must be verbose, dammit);
// TODO (Aramis)
// If we had a model format in the lib which has native support for
// tangents and bitangents, it would be necessary to add a
// "KillTangentsAndBitangents" flag ...
if (pMesh->mTangents && pMesh->mBitangents)
{
return false;
}
// what we can check, though, is if the mesh has normals and texture coord. That's a requirement // what we can check, though, is if the mesh has normals and texture coord. That's a requirement
if( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL) if( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL)
return; {
DefaultLogger::get()->error("Normal vectors and at least one "
"texture coordinate set are required to calculate tangents. ");
return false;
}
// calculate the position bounds so we have a reliable epsilon to check position differences against // calculate the position bounds so we have a reliable epsilon to check position differences against
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
@ -229,4 +244,5 @@ void CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
meshBitang[ closeVertices[b] ] = smoothBitangent; meshBitang[ closeVertices[b] ] = smoothBitangent;
} }
} }
return true;
} }

View File

@ -89,7 +89,7 @@ protected:
/** Calculates tangents and bitangents for the given mesh /** Calculates tangents and bitangents for the given mesh
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
*/ */
void ProcessMesh( aiMesh* pMesh); bool ProcessMesh( aiMesh* pMesh);
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -51,7 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
DefaultLogger *DefaultLogger::m_pLogger = NULL; NullLogger DefaultLogger::s_pNullLogger;
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// //
@ -72,17 +73,29 @@ struct LogStreamInfo
// Creates the only singleton instance // Creates the only singleton instance
Logger *DefaultLogger::create(const std::string &name, LogSeverity severity) Logger *DefaultLogger::create(const std::string &name, LogSeverity severity)
{ {
ai_assert (NULL == m_pLogger);
m_pLogger = new DefaultLogger( name, severity ); m_pLogger = new DefaultLogger( name, severity );
return m_pLogger; return m_pLogger;
} }
// ---------------------------------------------------------------------------
void DefaultLogger::set (Logger *logger)
{
if (!logger)
{
DefaultLogger::m_pLogger = &s_pNullLogger;
return;
}
DefaultLogger::m_pLogger = logger;
}
// ---------------------------------------------------------------------------
bool DefaultLogger::isNullLogger()
{
return m_pLogger == &s_pNullLogger;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Singleton getter // Singleton getter
Logger *DefaultLogger::get() Logger *DefaultLogger::get()
{ {
ai_assert (NULL != m_pLogger);
return m_pLogger; return m_pLogger;
} }
@ -92,7 +105,7 @@ void DefaultLogger::kill()
{ {
ai_assert (NULL != m_pLogger); ai_assert (NULL != m_pLogger);
delete m_pLogger; delete m_pLogger;
m_pLogger = NULL; m_pLogger = &s_pNullLogger;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -143,6 +156,22 @@ void DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
{ {
ai_assert ( NULL != pStream ); ai_assert ( NULL != pStream );
// fix (Aramis)
if (0 == severity)
{
severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
}
for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end();
++it )
{
if ( (*it)->m_pStream == pStream )
{
(*it)->m_uiErrorSeverity |= severity;
}
}
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream ); LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
m_StreamArray.push_back( pInfo ); m_StreamArray.push_back( pInfo );
} }
@ -153,6 +182,12 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{ {
ai_assert ( NULL != pStream ); ai_assert ( NULL != pStream );
// fix (Aramis)
if (0 == severity)
{
severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
}
for ( StreamIt it = m_StreamArray.begin(); for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it ) ++it )
@ -166,6 +201,9 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
uiSev &= ( ~Logger::WARN ); uiSev &= ( ~Logger::WARN );
if ( severity & Logger::ERR ) if ( severity & Logger::ERR )
uiSev &= ( ~Logger::ERR ); uiSev &= ( ~Logger::ERR );
// fix (Aramis)
if ( severity & Logger::DEBUGGING )
uiSev &= ( ~Logger::DEBUGGING );
(*it)->m_uiErrorSeverity = uiSev; (*it)->m_uiErrorSeverity = uiSev;

View File

@ -38,6 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#if (!defined AI_DEFAULTLOGGER_H_INCLUDED)
#define AI_DEFAULTLOGGER_H_INCLUDED
#include "../include/Logger.h" #include "../include/Logger.h"
#include <vector> #include <vector>
@ -47,6 +50,39 @@ namespace Assimp
class IOStream; class IOStream;
struct LogStreamInfo; struct LogStreamInfo;
// ---------------------------------------------------------------------------
/** @class NullLogger
* @brief Empty logging implementation. Does nothing. Used by default
* if the application hasn't specified a custom logger (or DefaultLogger)
* via DefaultLogger::set() or DefaultLogger::create();
*/
class NullLogger : public Logger
{
public:
/** @brief Logs a debug message */
void debug(const std::string &message) {}
/** @brief Logs an info message */
void info(const std::string &message) {}
/** @brief Logs a warning message */
void warn(const std::string &message) {}
/** @brief Logs an error message */
void error(const std::string &message) {}
/** @brief Log severity setter */
void setLogSeverity(LogSeverity log_severity) {}
/** @brief Detach a still attached stream from logger */
void attachStream(LogStream *pStream, unsigned int severity) {}
/** @brief Detach a still attached stream from logger */
void detatchStream(LogStream *pStream, unsigned int severity) {}
};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @class DefaultLogger /** @class DefaultLogger
* @brief Default logging implementation. The logger writes into a file. * @brief Default logging implementation. The logger writes into a file.
@ -57,18 +93,39 @@ class DefaultLogger :
public Logger public Logger
{ {
public: public:
/** @brief Creates the only logging instance /** @brief Creates a custom logging instance (DefaultLogger)
* @param name Name for logfile * @param name Name for logfile
* @param severity Log severity, VERBOSE will activate debug messages * @param severity Log severity, VERBOSE will activate debug messages
*
* This replaces the default NullLogger with a DefaultLogger instance.
*/ */
static Logger *create(const std::string &name, LogSeverity severity); static Logger *create(const std::string &name, LogSeverity severity);
/** @brief Setup a custom implementation of the Logger interface as
* default logger.
*
* Use this if the provided DefaultLogger class doesn't fit into
* your needs. If the provided message formatting is OK for you,
* it is easier to use create() to create a DefaultLogger and to attach
* your own custom output streams to it than using this method.
* @param logger Pass NULL to setup a default NullLogger
*/
static void set (Logger *logger);
/** @brief Getter for singleton instance /** @brief Getter for singleton instance
* @return Only instance * @return Only instance. This is never null, but it could be a
* NullLogger. Use isNullLogger to check this.
*/ */
static Logger *get(); static Logger *get();
/** @brief Will kill the singleton instance */ /** @brief Return whether a default NullLogger is currently active
* @return true if the current logger id a NullLogger.
* Use create() or set() to setup a custom logger.
*/
static bool isNullLogger();
/** @brief Will kill the singleton instance and setup a NullLogger as
logger */
static void kill(); static void kill();
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */ /** @brief Logs debug infos, only been written when severity level VERBOSE is set */
@ -112,7 +169,9 @@ private:
typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt; typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
//! only logging instance //! only logging instance
static DefaultLogger *m_pLogger; static Logger *m_pLogger;
static NullLogger s_pNullLogger;
//! Logger severity //! Logger severity
LogSeverity m_Severity; LogSeverity m_Severity;
//! Attached streams //! Attached streams
@ -123,3 +182,5 @@ private:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp
#endif // !! AI_DEFAULTLOGGER_H_INCLUDED

View File

@ -109,6 +109,9 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
aiVector3D pDelta2 = *pV3 - *pV1; aiVector3D pDelta2 = *pV3 - *pV1;
aiVector3D vNor = pDelta1 ^ pDelta2; aiVector3D vNor = pDelta1 ^ pDelta2;
if (face.mIndices[1] > face.mIndices[2])
vNor *= -1.0f;
for (unsigned int i = 0;i < face.mNumIndices;++i) for (unsigned int i = 0;i < face.mNumIndices;++i)
{ {
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;

View File

@ -110,6 +110,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
aiVector3D pDelta2 = *pV3 - *pV1; aiVector3D pDelta2 = *pV3 - *pV1;
aiVector3D vNor = pDelta1 ^ pDelta2; aiVector3D vNor = pDelta1 ^ pDelta2;
if (face.mIndices[1] > face.mIndices[2])
vNor *= -1.0f;
for (unsigned int i = 0;i < face.mNumIndices;++i) for (unsigned int i = 0;i < face.mNumIndices;++i)
{ {
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;

View File

@ -99,10 +99,6 @@ Importer::Importer() :
mScene(NULL), mScene(NULL),
mErrorString("") mErrorString("")
{ {
// construct a new logger
/*DefaultLogger::create( "test.log", DefaultLogger::VERBOSE );
DefaultLogger::get()->info("Start logging");*/
// allocate a default IO handler // allocate a default IO handler
mIOHandler = new DefaultIOSystem; mIOHandler = new DefaultIOSystem;

View File

@ -244,6 +244,7 @@ void MD2Importer::InternReadFile(
unsigned int iCurrent = 0; unsigned int iCurrent = 0;
if (0 != this->m_pcHeader->numTexCoords) if (0 != this->m_pcHeader->numTexCoords)
{ {
for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i) for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i)
{ {
// allocate the face // allocate the face
@ -253,10 +254,9 @@ void MD2Importer::InternReadFile(
// copy texture coordinates // copy texture coordinates
// check whether they are different from the previous value at this index. // check whether they are different from the previous value at this index.
// In this case, create a full separate set of vertices/normals/texcoords // In this case, create a full separate set of vertices/normals/texcoords
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
// validate vertex indices // validate vertex indices
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices) if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1; pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
@ -295,6 +295,9 @@ void MD2Importer::InternReadFile(
pcOut->x = u; pcOut->x = u;
pcOut->y = v; pcOut->y = v;
} }
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
} }
} }
else else
@ -308,10 +311,9 @@ void MD2Importer::InternReadFile(
// copy texture coordinates // copy texture coordinates
// check whether they are different from the previous value at this index. // check whether they are different from the previous value at this index.
// In this case, create a full separate set of vertices/normals/texcoords // In this case, create a full separate set of vertices/normals/texcoords
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
// validate vertex indices // validate vertex indices
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices) if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1; pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
@ -343,6 +345,9 @@ void MD2Importer::InternReadFile(
pcOut->x = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / this->m_pcHeader->skinWidth; pcOut->x = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / this->m_pcHeader->skinWidth;
pcOut->y = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / this->m_pcHeader->skinHeight; pcOut->y = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / this->m_pcHeader->skinHeight;
} }
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
} }
} }

View File

@ -254,7 +254,7 @@ struct Vertex
* \note This has been taken from q3 source (misc_model.c) * \note This has been taken from q3 source (misc_model.c)
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut) inline void LatLngNormalToVec3(int16_t p_iNormal, float* p_afOut)
{ {
float lat = (float)(( p_iNormal >> 8 ) & 0xff); float lat = (float)(( p_iNormal >> 8 ) & 0xff);
float lng = (float)(( p_iNormal & 0xff )); float lng = (float)(( p_iNormal & 0xff ));

View File

@ -201,25 +201,28 @@ void MD3Importer::InternReadFile(
pcMesh->mFaces[i].mIndices = new unsigned int[3]; pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3; pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices // read vertices
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X; pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X;
pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y; pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y;
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z * -1.0f; pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z*-1.0f;
// convert the normal vector to uncompressed float3 format // convert the normal vector to uncompressed float3 format
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL, LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
(float*)&pcMesh->mNormals[iCurrent]); (float*)&pcMesh->mNormals[iCurrent]);
std::swap ( pcMesh->mNormals[iCurrent].y,pcMesh->mNormals[iCurrent].z ); //std::swap(pcMesh->mNormals[iCurrent].z,pcMesh->mNormals[iCurrent].y);
pcMesh->mNormals[iCurrent].z *= -1.0f;
// read texture coordinates // read texture coordinates
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U; pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[ pcTriangles->INDEXES[c]].V; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[ pcTriangles->INDEXES[c]].V;
} }
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
pcTriangles++; pcTriangles++;
} }

View File

@ -654,6 +654,7 @@ void MDLImporter::InternReadFile_Quake1( )
pcMesh->mFaces[i].mIndices = new unsigned int[3]; pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3; pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pcMesh->mFaces[i].mIndices[c] = iCurrent; pcMesh->mFaces[i].mIndices[c] = iCurrent;
@ -705,6 +706,9 @@ void MDLImporter::InternReadFile_Quake1( )
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / this->m_pcHeader->skinheight; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / this->m_pcHeader->skinheight;
} }
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
pcTriangles++; pcTriangles++;
} }
return; return;
@ -824,10 +828,9 @@ void MDLImporter::InternReadFile_GameStudio( )
pcMesh->mFaces[i].mIndices = new unsigned int[3]; pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3; pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices // read vertices
unsigned int iIndex = pcTriangles->index_xyz[c]; unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts) if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
@ -879,6 +882,9 @@ void MDLImporter::InternReadFile_GameStudio( )
vTexCoords[iCurrent].x = s; vTexCoords[iCurrent].x = s;
vTexCoords[iCurrent].y = t; vTexCoords[iCurrent].y = t;
} }
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
pcTriangles++; pcTriangles++;
} }
@ -901,10 +907,9 @@ void MDLImporter::InternReadFile_GameStudio( )
pcMesh->mFaces[i].mIndices = new unsigned int[3]; pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3; pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent) for (unsigned int c = 0; c < 3;++c,++iCurrent)
{ {
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices // read vertices
unsigned int iIndex = pcTriangles->index_xyz[c]; unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts) if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
@ -956,6 +961,9 @@ void MDLImporter::InternReadFile_GameStudio( )
vTexCoords[iCurrent].x = s; vTexCoords[iCurrent].x = s;
vTexCoords[iCurrent].y = t; vTexCoords[iCurrent].y = t;
} }
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
pcTriangles++; pcTriangles++;
} }
} }
@ -1384,7 +1392,7 @@ void MDLImporter::InternReadFile_GameStudioA7( )
unsigned int iOutIndex = iTriangle * 3 + c; unsigned int iOutIndex = iTriangle * 3 + c;
// write the output face index // write the output face index
pcFaces[iTriangle].mIndices[c] = iOutIndex; pcFaces[iTriangle].mIndices[c] = iTriangle * 3 + (2-c);
// swap z and y axis // swap z and y axis
vPositions[iOutIndex].x = _AI_MDL7_ACCESS_VERT(pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .x; vPositions[iOutIndex].x = _AI_MDL7_ACCESS_VERT(pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .x;

View File

@ -0,0 +1,221 @@
/*
---------------------------------------------------------------------------
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 Implementation of the post processing step "MakeVerboseFormat"
*/
#include "MakeVerboseFormat.h"
#include "DefaultLogger.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
#include "../include/aiAssert.h"
using namespace Assimp;
MakeVerboseFormatProcess::MakeVerboseFormatProcess()
{
// nothing to do here
}
MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
{
// nothing to do here
}
// -------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void MakeVerboseFormatProcess::Execute( aiScene* pScene)
{
ai_assert(NULL != pScene);
DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{
if( this->MakeVerboseFormat( pScene->mMeshes[a]))
bHas = true;
}
if (bHas)DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
}
// -------------------------------------------------------------------
// Executes the post processing step on the given imported data.
bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
{
ai_assert(NULL != pcMesh);
unsigned int iOldNumVertices = pcMesh->mNumVertices;
const unsigned int iNumVerts = pcMesh->mNumFaces*3;
aiVector3D* pvPositions = new aiVector3D[iNumVerts];
aiVector3D* pvNormals;
if (pcMesh->HasNormals())
{
pvNormals = new aiVector3D[iNumVerts];
}
aiVector3D* pvTangents, *pvBitangents;
if (pcMesh->HasTangentsAndBitangents())
{
pvTangents = new aiVector3D[iNumVerts];
pvBitangents = new aiVector3D[iNumVerts];
}
ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == 4);
ai_assert(AI_MAX_NUMBER_OF_COLOR_SETS == 4);
aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {NULL,NULL,NULL,NULL};
aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {NULL,NULL,NULL,NULL};
unsigned int p = 0;
while (pcMesh->HasTextureCoords(p))
apvTextureCoords[p++] = new aiVector3D[iNumVerts];
p = 0;
while (pcMesh->HasVertexColors(p))
apvColorSets[p++] = new aiColor4D[iNumVerts];
// allocate enough memory to hold output bones and vertex weights ...
std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
{
newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
}
// iterate through all faces and build a clean list
unsigned int iIndex = 0;
for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
{
aiFace* pcFace = &pcMesh->mFaces[a];
for (unsigned int q = 0; q < 3;++q,++iIndex)
{
// need to build a clean list of bones, too
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
{
for (unsigned int a = 0; a < pcMesh->mBones[i]->mNumWeights;a++)
{
const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
if(pcFace->mIndices[q] == w.mVertexId)
{
aiVertexWeight wNew;
wNew.mVertexId = iIndex;
wNew.mWeight = w.mWeight;
newWeights[i].push_back(wNew);
}
}
}
pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
if (pcMesh->HasNormals())
{
pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
}
if (pcMesh->HasTangentsAndBitangents())
{
pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
}
unsigned int p = 0;
while (pcMesh->HasTextureCoords(p))
{
apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
++p;
}
p = 0;
while (pcMesh->HasVertexColors(p))
{
apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
++p;
}
pcFace->mIndices[q] = iIndex;
}
}
// build output vertex weights
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
{
delete pcMesh->mBones[i]->mWeights;
if (!newWeights[i].empty())
{
pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
memcpy(pcMesh->mBones[i]->mWeights,&newWeights[i][0],
sizeof(aiVertexWeight) * newWeights[i].size());
}
else pcMesh->mBones[i]->mWeights = NULL;
}
// delete the old members
delete[] pcMesh->mVertices;
pcMesh->mVertices = pvPositions;
p = 0;
while (pcMesh->HasTextureCoords(p))
{
delete pcMesh->mTextureCoords[p];
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
++p;
}
p = 0;
while (pcMesh->HasVertexColors(p))
{
delete pcMesh->mColors[p];
pcMesh->mColors[p] = apvColorSets[p];
++p;
}
pcMesh->mNumVertices = iNumVerts;
if (pcMesh->HasNormals())
{
delete[] pcMesh->mNormals;
pcMesh->mNormals = pvNormals;
}
if (pcMesh->HasTangentsAndBitangents())
{
delete[] pcMesh->mTangents;
pcMesh->mTangents = pvTangents;
delete[] pcMesh->mBitangents;
pcMesh->mBitangents = pvBitangents;
}
return (pcMesh->mNumVertices != iOldNumVertices);
}

View File

@ -0,0 +1,106 @@
/*
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 bring a given scene
into the verbose format that is expected by most postprocess steps.
This is the inverse of the "JoinIdenticalVertices" steps */
#ifndef AI_MAKEVERBOSEFORMAT_H_INC
#define AI_MAKEVERBOSEFORMAT_H_INC
#include "BaseProcess.h"
#include "../include/aiMesh.h"
namespace Assimp
{
// ---------------------------------------------------------------------------
/** MakeVerboseFormatProcess: Class to convert an asset to the verbose
* format which is expected by most postprocess steps.
*
* This is the inverse of what the "JoinIdenticalVertices" step is doing.
* This step has no official flag (since it wouldn't make sense to run it
* during import). It is intended for applications intending to modify the
* returned aiScene. After this step has been executed, they can execute
* other postprocess steps on the data.
* The step has been added because it was required by the viewer, however
* it has been moved to the main library since others might find it
* useful, too.
*/
class MakeVerboseFormatProcess : public BaseProcess
{
friend class Importer;
public:
/** Constructor to be privately used by Importer, or by applications
which know what they are doing if they modify the aiScene object */
MakeVerboseFormatProcess();
/** Destructor, private as well */
~MakeVerboseFormatProcess();
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
{
// NOTE: There is no direct flag that corresponds to
// this postprocess step.
return false;
}
// -------------------------------------------------------------------
/** 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);
private:
//! Apply the postprocess step to a given submesh
bool MakeVerboseFormat (aiMesh* pcMesh);
};
}; // end of namespace Assimp
#endif // !!AI_KILLNORMALPROCESS_H_INC

View File

@ -64,7 +64,7 @@ aiReturn aiSetVertexSplitLimit(unsigned int pLimit)
} }
SplitLargeMeshesProcess_Vertex::LIMIT = pLimit; SplitLargeMeshesProcess_Vertex::LIMIT = pLimit;
//DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed"); DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
return AI_SUCCESS; return AI_SUCCESS;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -77,7 +77,7 @@ aiReturn aiSetTriangleSplitLimit(unsigned int pLimit)
} }
SplitLargeMeshesProcess_Triangle::LIMIT = pLimit; SplitLargeMeshesProcess_Triangle::LIMIT = pLimit;
//DefaultLogger::get()->debug("aiSetTriangleSplitLimit() - triangle split limit was changed"); DefaultLogger::get()->debug("aiSetTriangleSplitLimit() - triangle split limit was changed");
return AI_SUCCESS; return AI_SUCCESS;
} }
}; //! extern "C" }; //! extern "C"

View File

@ -570,7 +570,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
// material colours // material colours
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); // FIX: Setup this as ambient not as emissive color
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT);
mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);

View File

@ -0,0 +1,134 @@
/*
---------------------------------------------------------------------------
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 Implementation of the JNI API for jAssimp */
#if (defined ASSIMP_JNI_EXPORT)
// include assimp
#include "../../include/aiTypes.h"
#include "../../include/aiMesh.h"
#include "../../include/aiAnim.h"
#include "../../include/aiScene.h"
#include "../../include/aiAssert.h"
#include "../../include/aiPostProcess.h"
#include "../../include/assimp.hpp"
#include "../DefaultLogger.h"
#include "JNILogger.h"
using namespace Assimp;
namespace Assimp {
namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
void JNILogDispatcher::SetJNIEnvironment(JNIEnv* ptr)
{
// there is much error handling code in this function.
// However, it is not impossible that the jAssimp package
// loaded by the JVM is incomplete ...
jclass java_lang_Exception = this->GetJNIEnv()->FindClass("java.lang.Exception");
// get a handle to the assimp.DefaultLogger class
this->m_pcJNIEnv = ptr;
if( NULL == (this->m_pcClass = this->GetJNIEnv()->FindClass("assimp.DefaultLogger")))
{
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
"Unable to get class handle to assimp.DefaultLogger");
return;
}
// get handles to the logging functions
if( NULL == (this->m_pcMethodError = this->GetJNIEnv()->GetStaticMethodID(
this->m_pcClass,"_NativeCallWriteError","(Ljava/lang/String;)V")))
{
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteError()");
return;
}
if( NULL == (this->m_pcMethodWarn = this->GetJNIEnv()->GetStaticMethodID(
this->m_pcClass,"_NativeCallWriteWarn","(Ljava/lang/String;)V")))
{
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteWarn()");
return;
}
if( NULL == (this->m_pcMethodInfo = this->GetJNIEnv()->GetStaticMethodID(
this->m_pcClass,"_NativeCallWriteInfo","(Ljava/lang/String;)V")))
{
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteInfo()");
return;
}
if( NULL == (this->m_pcMethodDebug = this->GetJNIEnv()->GetStaticMethodID(
this->m_pcClass,"_NativeCallWriteDebug","(Ljava/lang/String;)V")))
{
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteDebug()");
}
}
// ------------------------------------------------------------------------------------------------
void JNILogDispatcher::debug(const std::string &message)
{
}
// ------------------------------------------------------------------------------------------------
void JNILogDispatcher::info(const std::string &message)
{
}
// ------------------------------------------------------------------------------------------------
void JNILogDispatcher::warn(const std::string &message)
{
}
// ------------------------------------------------------------------------------------------------
void JNILogDispatcher::error(const std::string &message)
{
}
};};
#endif // jni

View File

@ -0,0 +1,122 @@
/*
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.
----------------------------------------------------------------------
*/
#if (!defined AI_JNILOGGER_H_INCLUDED)
#define AI_JNILOGGER_H_INCLUDED
#include "../../include/Logger.h"
#include <vector>
#include <jni.h>
namespace Assimp {
namespace JNIBridge {
// ---------------------------------------------------------------------------
class IOStream;
struct LogStreamInfo;
// ---------------------------------------------------------------------------
/** @class JNILogDispatcher
* @brief Logging system implementation that is used to send all
* log messages generated by native code to the Java logging system.
*/
class JNILogDispatcher : public Logger
{
public:
/** @brief Logs a debug message */
void debug(const std::string &message);
/** @brief Logs an info message */
void info(const std::string &message);
/** @brief Logs a warning message */
void warn(const std::string &message);
/** @brief Logs an error message */
void error(const std::string &message);
/** @brief Log severity setter */
void setLogSeverity(LogSeverity log_severity) {}
/** @brief Detach a still attached stream from logger */
void attachStream(LogStream *pStream, unsigned int severity) {}
/** @brief Detach a still attached stream from logger */
void detatchStream(LogStream *pStream, unsigned int severity) {}
//! Setup the JNI environment to use
//! (must be attached to the thread)
//! \param ptr Java environment to be used. != 0
void SetJNIEnvironment(JNIEnv* ptr);
//! Get the current JNI environment
inline JNIEnv* GetJNIEnv()
{
ai_assert(NULL != m_pcJNIEnv);
return m_pcJNIEnv;
}
private:
//! JNI environment pointer
JNIEnv* m_pcJNIEnv;
//! Handle to assimp.DefaultLogger class
jclass m_pcClass;
//! Handle to the static assimp.DefaultLogger._NativeCallWriteError() method
jmethodID m_pcMethodError;
//! Handle to the static assimp.DefaultLogger._NativeCallWriteInfo() method
jmethodID m_pcMethodInfo;
//! Handle to the static assimp.DefaultLogger._NativeCallWriteDebug() method
jmethodID m_pcMethodDebug;
//! Handle to the static assimp.DefaultLogger._NativeCallWriteWarn() method
jmethodID m_pcMethodWarn;
};
};};
#endif // AI_JNILOGGER_H_INCLUDED

View File

@ -269,9 +269,15 @@ public:
/** @def AI_MATKEY_SHININESS /** @def AI_MATKEY_SHININESS
* Defines the base shininess of the material * Defines the base shininess of the material
* This is the exponent of the phong shading equation.
*/ */
#define AI_MATKEY_SHININESS "$mat.shininess" #define AI_MATKEY_SHININESS "$mat.shininess"
/** @def AI_MATKEY_SHININESS_STRENGTH
* Defines the strength of the specular highlight.
*/
#define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent"
/** @def AI_MATKEY_COLOR_DIFFUSE /** @def AI_MATKEY_COLOR_DIFFUSE
* Defines the diffuse base color of the material * Defines the diffuse base color of the material
*/ */

View File

@ -50,7 +50,7 @@ package assimp;
* @author Aramis (Alexander Gessler) * @author Aramis (Alexander Gessler)
* @version 1.0 * @version 1.0
*/ */
public class Animation extends IMappable { public class Animation extends Mappable {
/** /**
* Construction from a given object and array index * Construction from a given object and array index
* *

View File

@ -0,0 +1,135 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
package assimp;
import java.awt.*;
/**
* Represents an embedded compressed texture that is stored in a format
* like JPEG or PNG. See the documentation of <code>Texture</code>
* for more details on this class. Use <code>instanceof</code> to
* determine whether a particular <code>Texture</code> in the list
* returned by <code>Scene.getTextures()</code> is a compressed texture.
* <p/>
*
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public class CompressedTexture extends Texture {
private String m_format = "";
private byte[] m_data;
private int m_length = 0;
/**
* Construction from a given parent object and array index
*
* @param parent Must be valid, null is not allowed
* @param index Valied index in the parent's list
*/
public CompressedTexture(Object parent, int index) throws NativeError {
super(parent, index);
}
/**
* Retrieves the format of the texture data. This is
* the most common file extension of the format (without a
* dot at the beginning). Examples include dds, png, jpg ...
* @return Extension string or null if the format of the texture
* data is not known to ASSIMP.
*/
public String getFormat() {
return m_format;
}
public byte[] getData() {
return m_data;
}
/**
* Retrieve the height of the texture image
*
* @return Height, in pixels
*/
public int getHeight() {
DefaultLogger.get()
return height;
}
/**
* Retrieve the width of the texture image
*
* @return Width, in pixels
*/
public int getWidth() {
return width;
}
/**
* Internal helper function to map the native texture data into
* a <code>byte</code> array in the memory of the JVM
*/
@Override
protected void OnMap() throws NativeError {
// first allocate the output array
data = new Color[iNumPixels];
// now allocate a temporary output array
byte[] temp = new byte[(iNumPixels) << 2];
// and copy the native color data to it
if (0xffffffff == this._NativeMapColorData(((Scene)this.getParent()).getImporter().getContext(),
this.getArrayIndex(),temp)) {
throw new NativeError("Unable to map aiTexture into the Java-VM");
}
// now convert the temporary representation to a Color array
// (data is given in BGRA order, we need RGBA)
for (int i = 0, iBase = 0; i < iNumPixels; ++i, iBase += 4) {
data[i] = new Color(temp[iBase + 2], temp[iBase + 1], temp[iBase], temp[iBase + 3]);
}
return;
}
}

View File

@ -0,0 +1,403 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
package assimp;
import java.util.Vector;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
/**
* Default implementation of a logger. When writing to the log,
* jASSIMP uses the <code>Logger</code> instance returned by
* <code>DefaultLogger.get()</code>
*
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public class DefaultLogger implements Logger {
/**
* Helper class to combine a logstream with an error severity
*/
private static class LogStreamInfo {
public LogStream stream;
public int severity;
public LogStreamInfo(LogStream stream, int severity) {
this.stream = stream;
this.severity = severity;
}
}
/**
* NULL logger class. Does nothing ...
*/
private static class NullLogger implements Logger {
public void debug(String message) {
} // nothing to do here ...
public void error(String message) {
} // nothing to do here ...
public void warn(String message) {
} // nothing to do here ...
public void info(String message) {
} // nothing to do here ...
public void attachStream(LogStream stream, int severity) {
} // nothing to do here ...
public void detachStream(LogStream stream, int severity) {
} // nothing to do here ...
}
/**
* Implementation of LogStream that can be used to use a
* <code>java.io.OutputStream</code> object directly as log stream.
*/
public static class StreamWrapper implements LogStream {
private OutputStream stream;
/**
* Construction from an existing <code>java.io.OutputStream</code> object
*
* @param stream May not be null
*/
public StreamWrapper(OutputStream stream) {
assert(null != stream);
this.stream = stream;
}
public void write(String message) {
try {
stream.write(message.getBytes(), 0, message.length());
} catch (IOException e) {
// .... should't care
}
}
public OutputStream getStream() {
return stream;
}
}
/**
* Implementation of LogStream that can be used to use a
* <code>java.io.FileWriter</code> object directly as log stream.
*/
public static class FileStreamWrapper implements LogStream {
private FileWriter stream;
/**
* Construction from an existing <code>java.io.FileWriter</code> object
*
* @param stream May not be null
*/
public FileStreamWrapper(FileWriter stream) {
assert(null != stream);
this.stream = stream;
}
public void write(String message) {
try {
stream.write(message);
} catch (IOException e) {
// .... should't care
}
}
public FileWriter getStream() {
return stream;
}
}
/**
* Normal granlality of logging
*/
public static final int LOGSEVERITY_NORMAL = 0x0;
/**
* Debug infos will be logged, too
*/
public static final int LOGSEVERITY_VERBOSE = 0x1;
/**
* Default logger. It does nothing and is used if the
* application hasn't allocated a default logger
*/
private static NullLogger s_nullLogger = new NullLogger();
/**
* The logger that is used by ASSIMP for logging
*/
private static Logger s_logger = s_nullLogger;
/**
* List of logstreams to output to
*/
private Vector<LogStreamInfo> m_avStreams;
/**
* One of the LOGSEVERITY_XXX constants.
*/
private int m_iLogSeverity = LOGSEVERITY_NORMAL;
private DefaultLogger() {
}
/**
* Create the default logger
*
* @param file Output log file. If != <code>null</code> this will
* automatically add a file log stream to the logger
* @param bErrOut If this is true an additional logstream which
* outputs all log messages via <code>System.err.println()</code>
* will be added to the logger.
*/
public static void create(String file, boolean bErrOut) throws IOException {
s_logger = new DefaultLogger();
if (null != file) {
FileWriter stream = new FileWriter(file);
s_logger.attachStream(new FileStreamWrapper(stream), 0);
}
if (bErrOut) {
s_logger.attachStream(new StreamWrapper(System.err), 0);
}
}
/**
* Create the default logger, no default log streams will be
* attached to it.
*/
public static void create() throws IOException {
create(null, false);
}
/**
* Supply your own implementation of <code>Logger</code> to the
* logging system. Use this if you want to override the default
* formatting behaviour of <code>DefaultLogger</code>. You can
* access your logger as normal, via <code>get()</code>.
*
* @param logger
*/
public static void set(Logger logger) {
s_logger = logger;
}
/**
* Kill the logger ... a null logger will be used instead
*/
public static void kill() {
s_logger = s_nullLogger;
}
/**
* Get access to the Singleton instance of the logger. This will
* never be null. If no logger has been explicitly created via
* <code>create()</code> this is a <code>NULLLogger</code> instance.
* Use <code>isNullLogger()</code> to check whether the returned logger
* is a null logger.
*
* @return Never null ...
*/
public static Logger get() {
return s_logger;
}
/**
* Check whether the current logger is a null logger, which
* doesn't log anything. Use <code>create()</code> or <code>set()</code>
* to setup another logger.
*
* @return true if the curent logger is a null logger (true by default)
*/
public static boolean isNullLogger() {
return (s_logger instanceof NullLogger);
}
/**
* Write a debug message to the log
*
* @param message Message to be logged
*/
public void debug(String message) {
this.writeToStreams("Debug:" + message + "\n", ERRORSEVERITY_DEBUGGING);
}
/**
* Write an error message to the log
*
* @param message Message to be logged
*/
public void error(String message) {
this.writeToStreams("Debug:" + message + "\n", ERRORSEVERITY_ERR);
}
/**
* Write a warn message to the log
*
* @param message Message to be logged
*/
public void warn(String message) {
this.writeToStreams("Debug:" + message + "\n", ERRORSEVERITY_WARN);
}
/**
* Write an info message to the log
*
* @param message Message to be logged
*/
public void info(String message) {
this.writeToStreams("Debug:" + message + "\n", ERRORSEVERITY_INFO);
}
/**
* Attach a logstream to the logger
*
* @param stream Log stream instance
* @param severity Error severity. Bitwise combination of the
* ERRORSEVERITY_XXX constants. Specify 0 to attach the
* stream to all types of log messages.
*/
public void attachStream(LogStream stream, int severity) {
if (0 == severity) {
severity = ERRORSEVERITY_DEBUGGING | ERRORSEVERITY_WARN |
ERRORSEVERITY_ERR | ERRORSEVERITY_INFO;
}
for (LogStreamInfo info : this.m_avStreams) {
if (info.stream != stream) continue;
info.severity |= severity;
severity = 0xcdcdcdcd;
}
if (0xcdcdcdcd != severity)
this.m_avStreams.add(new LogStreamInfo(stream, severity));
}
/**
* Detach a logstream from the logger
*
* @param stream Log stream instance
* @param severity Error severities to detach the stream from.
* Bitwise combination of the ERRORSEVERITY_XXX constants.
* Specify 0 to detach the stream from all types of log messages.
*/
public void detachStream(LogStream stream, int severity) {
if (0 == severity) {
severity = ERRORSEVERITY_DEBUGGING | ERRORSEVERITY_WARN |
ERRORSEVERITY_ERR | ERRORSEVERITY_INFO;
}
for (LogStreamInfo info : this.m_avStreams) {
if (info.stream != stream) continue;
if (0 != (severity & ERRORSEVERITY_DEBUGGING)) {
info.severity &= (~ERRORSEVERITY_DEBUGGING);
}
if (0 != (severity & ERRORSEVERITY_ERR)) {
info.severity &= (~ERRORSEVERITY_ERR);
}
if (0 != (severity & ERRORSEVERITY_INFO)) {
info.severity &= (~ERRORSEVERITY_INFO);
}
if (0 != (severity & ERRORSEVERITY_WARN)) {
info.severity &= (~ERRORSEVERITY_WARN);
}
if (0 == info.severity) {
this.m_avStreams.remove(info);
}
break;
}
}
private void writeToStreams(String message, int severity) {
for (LogStreamInfo info : this.m_avStreams) {
if (0 == (info.severity & severity)) continue;
info.stream.write(message);
}
}
// Helpers to make the access to the logging system easier
// for native code
public static void _NativeCallWriteError(String message) {
DefaultLogger.get().error(message);
}
public static void _NativeCallWriteWarn(String message) {
DefaultLogger.get().warn(message);
}
public static void _NativeCallWriteInfo(String message) {
DefaultLogger.get().info(message);
}
public static void _NativeCallWriteDebug(String message) {
DefaultLogger.get().debug(message);
}
}

View File

@ -0,0 +1,62 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
package assimp;
/**
* Output stream for the logger. Directly corresponding with the native
* LoggStream interface
* <br>
* For direct output to a <code>java.io.Stream</code> you can use the
* DefaultLogStream class.
*
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public interface LogStream {
/**
* Override this for your own output implementations
* @param message Message to be written to the log stream
*/
public void write(String message);
}

View File

@ -1,11 +1,116 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
package assimp; package assimp;
/** /**
* Created by IntelliJ IDEA. * Base logging interface. Directly corresponding with the native
* User: Alex * Logger interface
* Date: 21.05.2008 *
* Time: 19:31:28 * @author Aramis (Alexander Gessler)
* To change this template use File | Settings | File Templates. * @version 1.0
*/ */
public interface Logger { public interface Logger {
/**
* Debug log message
*/
public static final int ERRORSEVERITY_DEBUGGING = 0x1;
/**
* Information log message
*/
public static final int ERRORSEVERITY_INFO = 0x2;
/**
* Warn log message
*/
public static final int ERRORSEVERITY_WARN = 0x4;
/**
* Error log message
*/
public static final int ERRORSEVERITY_ERR = 0x8;
/**
* Write a debug message to the log
* @param message Message to be logged
*/
public void debug(String message);
/**
* Write an error message to the log
* @param message Message to be logged
*/
public void error(String message);
/**
* Write a warn message to the log
* @param message Message to be logged
*/
public void warn(String message);
/**
* Write an info message to the log
* @param message Message to be logged
*/
public void info(String message);
/**
* Attach a logstream to the logger
* @param stream Log stream instance
* @param severity Error severity. Bitwise combination of the
* ERRORSEVERITY_XXX constants. Specify 0 to attach the
* stream to all types of log messages.
*/
public void attachStream(LogStream stream, int severity);
/**
* Detach a logstream from the logger
* @param stream Log stream instance
* @param severity Error severities to detach the stream from.
* Bitwise combination of the ERRORSEVERITY_XXX constants.
* Specify 0 to detach the stream from all types of log messages.
*/
public void detachStream(LogStream stream, int severity);
} }

View File

@ -51,7 +51,7 @@ package assimp;
* @author Aramis (Alexander Gessler) * @author Aramis (Alexander Gessler)
* @version 1.0 * @version 1.0
*/ */
public class Material extends IMappable { public class Material extends Mappable {
/** /**
* Construction from a given parent object and array index * Construction from a given parent object and array index
* *

View File

@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package assimp; package assimp;
import java.lang.ref.Reference;
import java.awt.*; import java.awt.*;
@ -61,7 +60,7 @@ import java.awt.*;
* @author Aramis (Alexander Gessler) * @author Aramis (Alexander Gessler)
* @version 1.0 * @version 1.0
*/ */
public class Mesh extends IMappable { public class Mesh extends Mappable {
/** /**
* Defines the maximum number of UV(W) channels that are available * Defines the maximum number of UV(W) channels that are available

View File

@ -50,18 +50,18 @@ import java.awt.*;
* Example file formats doing this include MDL3, MDL5 and MDL7 (3D GameStudio). * Example file formats doing this include MDL3, MDL5 and MDL7 (3D GameStudio).
* Embedded textures are converted to an array of color values (RGBA). * Embedded textures are converted to an array of color values (RGBA).
* <p/> * <p/>
* Embedded textures in compressed file formats, such as JPEG or DDS * Compressed textures (textures that are stored in a format like png or jpg)
* are NOT supported by jAssimp. * are represented by the <code><CompressedTexture/code> class.
* *
* @author Aramis (Alexander Gessler) * @author Aramis (Alexander Gessler)
* @version 1.0 * @version 1.0
*/ */
public class Texture extends IMappable { public class Texture extends Mappable {
private int width = 0; protected int width = 0;
private int height = 0; protected int height = 0;
private Color[] data = null; protected Color[] data = null;
/** /**
* Construction from a given parent object and array index * Construction from a given parent object and array index

View File

@ -0,0 +1,183 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
package assimp.test;
import assimp.*;
import java.io.FileWriter;
import java.io.IOException;
/**
* Example class to demonstrate how to use jAssimp to load an asset from
* a file. The Main() method expects two parameters, the first being
* the path to the file to be opened, the second being the output path.
* The class writes a text file with the asset data inside.
*/
public class DumpToFile {
public static void Main(String[] arguments) throws IOException {
/* Use output.txt as default output file if none was specified
* However, at least one parameter is expected
*/
if (1 == arguments.length) {
String s = arguments[0];
arguments = new String[2];
arguments[0] = s;
arguments[1] = "output.txt";
}
else if (2 != arguments.length)return;
FileWriter stream;
try {
stream = new FileWriter(arguments[1]);
} catch (IOException e) {
e.printStackTrace();
System.out.println("Unable to open output file");
throw e;
}
/* Try to create an instance of class assimp.Importer.
* The constructor throws an assimp.NativeError exception
* if the native jAssimp library is not available.It must
* be placed in the jar/class directory of the application
*/
Importer imp;
try {
imp = new Importer();
} catch (NativeError nativeError) {
nativeError.printStackTrace();
System.out.println("NativeError exception [#1]: " + nativeError.getMessage());
return;
}
/* Now setup the correct postprocess steps. Triangulation is
* automatically performed, DX conversion is not necessary,
* However, a few steps are normally useful. Especially
* JoinVertices since it will dramantically reduce the size
* of the output file
*/
imp.addPostProcessStep(PostProcessStep.CalcTangentSpace);
imp.addPostProcessStep(PostProcessStep.GenSmoothNormals);
imp.addPostProcessStep(PostProcessStep.JoinIdenticalVertices);
/* Load the asset into memory. Again, a NativeError exception
* could be thrown if an unexpected errors occurs in the
* native interface. If assimp is just unable to load the asset
* null is the return value and no exception is thrown
*/
Scene scene;
try {
scene = imp.readFile(arguments[0]);
} catch (NativeError nativeError) {
nativeError.printStackTrace();
System.out.println("NativeError exception [#2] :" + nativeError.getMessage());
return;
}
if (null == scene) {
System.out.println("Unable to load asset: " + arguments[0]);
return;
}
/* Now iterate through all meshes that have been loaded
*/
int iMesh = 0;
for (Mesh mesh : scene.getMeshes()) {
stream.write("Mesh " + iMesh + "\n");
stream.write("\tNum Vertices: " + mesh.getNumVertices() + "\n");
stream.write("\tNum Faces: " + mesh.getNumFaces() + "\n");
stream.write("\tNum Bones: " + mesh.getNumBones() + "\n\n");
/* Output all vertices. First get direct access to jAssimp's buffers
* UV coords and colors could also be there, but we don't output them
* at the moment!
*/
float[] positions = mesh.getPositionArray();
float[] normals = mesh.getNormalArray();
float[] tangents = mesh.getTangentArray();
float[] bitangents = mesh.getBitangentArray();
for (int i = 0;i < mesh.getNumVertices();++i) {
// format: "Vertex pos(x|y|z) nor(x|y|z) tan(x|y|) bit(x|y|z)"
// great that this IDE is automatically able to replace + with append ... ;-)
stream.write(new StringBuilder().
append("\tVertex: pos(").
append(positions[i * 3]).append("|").
append(positions[i * 3 + 1]).append("|").
append(positions[i * 3 + 2]).append(")\t").
append("nor(").
append(normals[i * 3]).append("|").
append(normals[i * 3 + 1]).append("|").
append(normals[i * 3 + 2]).append(")\t").
append("tan(").
append(tangents[i * 3]).append("|").
append(tangents[i * 3 + 1]).append("|").
append(tangents[i * 3 + 2]).append(")\t").
append("bit(").
append(bitangents[i * 3]).append("|").
append(bitangents[i * 3 + 1]).append("|").
append(bitangents[i * 3 + 2]).append(")\n").toString());
}
stream.write("\n\n");
/* Now write a list of all faces in this model
*/
int[] faces = mesh.getFaceArray();
for (int i = 0; i < mesh.getNumFaces();++i) {
stream.write(new StringBuilder().append("\tFace (").
append(faces[i * 3]).append("|").
append(faces[i * 3 + 1]).append("|").
append(faces[i * 3 + 2]).append(")\n").toString());
}
++iMesh;
}
stream.close();
}
}

View File

@ -178,6 +178,9 @@ class AssetHelper
// shininess for the material // shininess for the material
float fShininess; float fShininess;
// strength of the specular highlight
float fSpecularStrength;
// Stores a pointer to the original normal set of the asset // Stores a pointer to the original normal set of the asset
aiVector3D* pvOriginalNormals; aiVector3D* pvOriginalNormals;
}; };

View File

@ -235,7 +235,6 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex]; g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex];
// update all meshes referencing this material // update all meshes referencing this material
this->m_pcCurrentTexture->piTexture = piTexture;
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
{ {
if (this->m_pcCurrentTexture->iMatIndex != g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) if (this->m_pcCurrentTexture->iMatIndex != g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
@ -249,6 +248,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piDiffuseTexture->Release(); pcMesh->piDiffuseTexture->Release();
pcMesh->piDiffuseTexture = piTexture; pcMesh->piDiffuseTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piDiffuseTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -261,6 +261,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piAmbientTexture->Release(); pcMesh->piAmbientTexture->Release();
pcMesh->piAmbientTexture = piTexture; pcMesh->piAmbientTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piAmbientTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -273,6 +274,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piSpecularTexture->Release(); pcMesh->piSpecularTexture->Release();
pcMesh->piSpecularTexture = piTexture; pcMesh->piSpecularTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piSpecularTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -285,6 +287,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piEmissiveTexture->Release(); pcMesh->piEmissiveTexture->Release();
pcMesh->piEmissiveTexture = piTexture; pcMesh->piEmissiveTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piEmissiveTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -297,6 +300,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piShininessTexture->Release(); pcMesh->piShininessTexture->Release();
pcMesh->piShininessTexture = piTexture; pcMesh->piShininessTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piShininessTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -310,6 +314,9 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piNormalTexture->Release(); pcMesh->piNormalTexture->Release();
pcMesh->piNormalTexture = piTexture; pcMesh->piNormalTexture = piTexture;
CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture,
&pcMesh->piNormalTexture,true);
this->m_pcCurrentTexture->piTexture = &pcMesh->piNormalTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -322,6 +329,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{ {
pcMesh->piOpacityTexture->Release(); pcMesh->piOpacityTexture->Release();
pcMesh->piOpacityTexture = piTexture; pcMesh->piOpacityTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piOpacityTexture;
if (!pcMesh->bSharedFX) if (!pcMesh->bSharedFX)
{ {
@ -414,32 +422,32 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType,
bool bIsExtraOpacity = 0 != (iType & 0x40000000); bool bIsExtraOpacity = 0 != (iType & 0x40000000);
const char* szType; const char* szType;
IDirect3DTexture9* piTexture; IDirect3DTexture9** piTexture;
switch (iType) switch (iType)
{ {
case AI_TEXTYPE_DIFFUSE: case AI_TEXTYPE_DIFFUSE:
piTexture = g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
szType = "Diffuse";break; szType = "Diffuse";break;
case AI_TEXTYPE_SPECULAR: case AI_TEXTYPE_SPECULAR:
piTexture = g_pcAsset->apcMeshes[iMesh]->piSpecularTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
szType = "Specular";break; szType = "Specular";break;
case AI_TEXTYPE_AMBIENT: case AI_TEXTYPE_AMBIENT:
piTexture = g_pcAsset->apcMeshes[iMesh]->piAmbientTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
szType = "Ambient";break; szType = "Ambient";break;
case AI_TEXTYPE_EMISSIVE: case AI_TEXTYPE_EMISSIVE:
piTexture = g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
szType = "Emissive";break; szType = "Emissive";break;
case AI_TEXTYPE_HEIGHT: case AI_TEXTYPE_HEIGHT:
piTexture = g_pcAsset->apcMeshes[iMesh]->piNormalTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
szType = "HeightMap";break; szType = "HeightMap";break;
case AI_TEXTYPE_NORMALS: case AI_TEXTYPE_NORMALS:
piTexture = g_pcAsset->apcMeshes[iMesh]->piNormalTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
szType = "NormalMap";break; szType = "NormalMap";break;
case AI_TEXTYPE_SHININESS: case AI_TEXTYPE_SHININESS:
piTexture = g_pcAsset->apcMeshes[iMesh]->piShininessTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
szType = "Shininess";break; szType = "Shininess";break;
default: // opacity + opacity | mask default: // opacity + opacity | mask
piTexture = g_pcAsset->apcMeshes[iMesh]->piOpacityTexture; piTexture = &g_pcAsset->apcMeshes[iMesh]->piOpacityTexture;
szType = "Opacity";break; szType = "Opacity";break;
}; };
if (bIsExtraOpacity) if (bIsExtraOpacity)
@ -466,7 +474,7 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType,
uint32_t iData = 0; uint32_t iData = 0;
DWORD dwSize = 4; DWORD dwSize = 4;
piTexture->GetPrivateData(guidPrivateData,&iData,&dwSize); (*piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
if (0xFFFFFFFF == iData) if (0xFFFFFFFF == iData)
{ {
@ -583,13 +591,27 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
} }
} }
AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[iIndex]; AssetHelper::MeshHelper* pcMesh = g_pcAsset->apcMeshes[iMesh];
if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity) if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity)
{ {
// seems the diffuse texture contains alpha, therefore it has been // check whether the diffuse texture is not a default texture
// added to the opacity channel, too. Add a special value ...
AddTextureToDisplayList(AI_TEXTYPE_OPACITY | 0x40000000, // {9785DA94-1D96-426b-B3CB-BADC36347F5E}
0,&szPath,hTexture,iUV,fBlend,eOp,iMesh); static const GUID guidPrivateData =
{ 0x9785da94, 0x1d96, 0x426b,
{ 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
uint32_t iData = 0;
DWORD dwSize = 4;
if(FAILED( pcMesh->piDiffuseTexture->GetPrivateData(guidPrivateData,&iData,&dwSize) ||
0xffffffff == iData))
{
// 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,
0,&szPath,hTexture,iUV,fBlend,eOp,iMesh);
}
} }
// add the material to the list // add the material to the list
@ -785,6 +807,17 @@ int CDisplay::Reset(void)
return this->OnSetupNormalView(); return this->OnSetupNormalView();
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
void UpdateColorFieldsInUI()
{
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE);
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
}
//-------------------------------------------------------------------------------
int CDisplay::OnSetupNormalView() int CDisplay::OnSetupNormalView()
{ {
// now ... change the meaning of the statistics fields back // now ... change the meaning of the statistics fields back
@ -804,6 +837,8 @@ int CDisplay::OnSetupNormalView()
this->m_pcCurrentTexture = NULL; this->m_pcCurrentTexture = NULL;
this->m_pcCurrentNode = NULL; this->m_pcCurrentNode = NULL;
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg); UpdateWindow(g_hDlg);
return 1; return 1;
} }
@ -829,6 +864,10 @@ int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew)
this->m_pcCurrentMaterial = pcNew; this->m_pcCurrentMaterial = pcNew;
this->SetViewMode(VIEWMODE_MATERIAL); this->SetViewMode(VIEWMODE_MATERIAL);
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg);
return 1; return 1;
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
@ -846,6 +885,14 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
"diffuse texture",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0)); "diffuse texture",D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0));
} }
// check whether the pattern background effect is supported
if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0))
{
CLogDisplay::Instance().AddEntry("[WARN] The background shader won't work "
"on your system, it required PS 3.0 hardware. A default color is used ...",
D3DCOLOR_ARGB(0xFF,0xFF,0x00,0));
}
this->m_fTextureZoom = 1000.0f; this->m_fTextureZoom = 1000.0f;
this->m_vTextureOffset.x = this->m_vTextureOffset.y = 0.0f; this->m_vTextureOffset.x = this->m_vTextureOffset.y = 0.0f;
@ -863,7 +910,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
// and fill them with data // and fill them with data
D3DSURFACE_DESC sDesc; D3DSURFACE_DESC sDesc;
pcNew->piTexture->GetLevelDesc(0,&sDesc); (*pcNew->piTexture)->GetLevelDesc(0,&sDesc);
char szTemp[128]; char szTemp[128];
sprintf(szTemp,"%i",sDesc.Width); sprintf(szTemp,"%i",sDesc.Width);
@ -872,7 +919,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
sprintf(szTemp,"%i",sDesc.Height); sprintf(szTemp,"%i",sDesc.Height);
SetWindowText(GetDlgItem(g_hDlg,IDC_ENODEWND),szTemp); SetWindowText(GetDlgItem(g_hDlg,IDC_ENODEWND),szTemp);
sprintf(szTemp,"%i",pcNew->piTexture->GetLevelCount()); sprintf(szTemp,"%i",(*pcNew->piTexture)->GetLevelCount());
SetWindowText(GetDlgItem(g_hDlg,IDC_ESHADER),szTemp); SetWindowText(GetDlgItem(g_hDlg,IDC_ESHADER),szTemp);
sprintf(szTemp,"%i",pcNew->iUV); sprintf(szTemp,"%i",pcNew->iUV);
@ -899,7 +946,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp); SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp);
// NOTE: Format is always ARGB8888 since other formats are // NOTE: Format is always ARGB8888 since other formats are
// convert to this format ... // converted to this format ...
SetWindowText(GetDlgItem(g_hDlg,IDC_EFACE),"ARGB8"); SetWindowText(GetDlgItem(g_hDlg,IDC_EFACE),"ARGB8");
// check whether this is the default texture // check whether this is the default texture
@ -912,7 +959,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
uint32_t iData = 0; uint32_t iData = 0;
DWORD dwSize = 4; DWORD dwSize = 4;
pcNew->piTexture->GetPrivateData(guidPrivateData,&iData,&dwSize); (*pcNew->piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
if (0xFFFFFFFF == iData) if (0xFFFFFFFF == iData)
{ {
@ -922,6 +969,8 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
return 0; return 0;
} }
} }
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg); UpdateWindow(g_hDlg);
return 1; return 1;
} }
@ -1047,14 +1096,6 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem)
return 1; return 1;
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
template <class type, class intype>
type clamp(intype in)
{
// for unsigned types only ...
intype mask = (0x1u << (sizeof(type)*8))-1;
return (type)std::max((intype)0,std::min(in,mask));
}
//-------------------------------------------------------------------------------
int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam) int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam)
{ {
// get the current selected material // get the current selected material
@ -1259,7 +1300,7 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam)
// get a pointer to the first surface of the current texture // get a pointer to the first surface of the current texture
IDirect3DSurface9* pi = NULL; IDirect3DSurface9* pi = NULL;
this->m_pcCurrentTexture->piTexture->GetSurfaceLevel(0,&pi); (*this->m_pcCurrentTexture->piTexture)->GetSurfaceLevel(0,&pi);
if(!pi || FAILED(D3DXSaveSurfaceToFile(szFileName,eFormat,pi,NULL,NULL))) if(!pi || FAILED(D3DXSaveSurfaceToFile(szFileName,eFormat,pi,NULL,NULL)))
{ {
CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture", CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture",
@ -1880,39 +1921,52 @@ int CDisplay::RenderPatternBG()
{ {
if (!g_piPatternEffect) if (!g_piPatternEffect)
{ {
// seems we have not yet compiled this shader. // the pattern effect won't work on ps_2_0 cards
// and NOW is the best time to do that ... if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3,0))
ID3DXBuffer* piBuffer = NULL;
if(FAILED( D3DXCreateEffect(g_piDevice,
g_szCheckerBackgroundShader.c_str(),
(UINT)g_szCheckerBackgroundShader.length(),
NULL,
NULL,
D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,
NULL,
&g_piPatternEffect,&piBuffer)))
{ {
// seems we have not yet compiled this shader.
// and NOW is the best time to do that ...
ID3DXBuffer* piBuffer = NULL;
if(FAILED( D3DXCreateEffect(g_piDevice,
g_szCheckerBackgroundShader.c_str(),
(UINT)g_szCheckerBackgroundShader.length(),
NULL,
NULL,
D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,
NULL,
&g_piPatternEffect,&piBuffer)))
{
if( piBuffer)
{
MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
piBuffer->Release();
}
return 0;
}
if( piBuffer) if( piBuffer)
{ {
MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
piBuffer->Release(); piBuffer->Release();
piBuffer = NULL;
} }
return 0;
} }
if( piBuffer) else
{ {
piBuffer->Release(); // clear the color buffer in magenta
piBuffer = NULL; // (hopefully this is ugly enough that every ps_2_0 cards owner
// runs to the next shop to buy himself a new card ...)
g_piDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 );
return 1;
} }
} }
// clear the color buffer in magenta
g_piDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, // clear the depth buffer only
g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,
D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 ); D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 );
if (!g_piPatternEffect) // setup the colors to be used ...
{ g_piPatternEffect->SetVector("COLOR_ONE",&this->m_avCheckerColors[0]);
return 0; g_piPatternEffect->SetVector("COLOR_TWO",&this->m_avCheckerColors[1]);
}
// setup the shader // setup the shader
UINT dw; UINT dw;
@ -1990,7 +2044,7 @@ int CDisplay::RenderTextureView()
sRect.bottom -= sRect.top; sRect.bottom -= sRect.top;
// commit the texture to the shader // commit the texture to the shader
g_piPassThroughEffect->SetTexture("TEXTURE_2D",this->m_pcCurrentTexture->piTexture); g_piPassThroughEffect->SetTexture("TEXTURE_2D",*this->m_pcCurrentTexture->piTexture);
if (AI_TEXTYPE_OPACITY == this->m_pcCurrentTexture->iType) if (AI_TEXTYPE_OPACITY == this->m_pcCurrentTexture->iType)
{ {
@ -2016,7 +2070,7 @@ int CDisplay::RenderTextureView()
// build a rectangle which centers the texture // build a rectangle which centers the texture
// scaling is OK, but no stretching // scaling is OK, but no stretching
D3DSURFACE_DESC sDesc; D3DSURFACE_DESC sDesc;
this->m_pcCurrentTexture->piTexture->GetLevelDesc(0,&sDesc); (*this->m_pcCurrentTexture->piTexture)->GetLevelDesc(0,&sDesc);
struct SVertex{float x,y,z,w,u,v;}; struct SVertex{float x,y,z,w,u,v;};
SVertex as[4]; SVertex as[4];

View File

@ -85,6 +85,9 @@ private:
this->m_aiImageList[2] = 2; this->m_aiImageList[2] = 2;
this->m_aiImageList[3] = 3; this->m_aiImageList[3] = 3;
this->m_aiImageList[4] = 4; this->m_aiImageList[4] = 4;
this->m_avCheckerColors[0].x = this->m_avCheckerColors[0].y = this->m_avCheckerColors[0].z = 0.4f;
this->m_avCheckerColors[0].x = this->m_avCheckerColors[1].y = this->m_avCheckerColors[2].z = 0.6f;
} }
public: public:
@ -112,7 +115,7 @@ public:
struct TextureInfo struct TextureInfo
{ {
// texture info // texture info
IDirect3DTexture9* piTexture; IDirect3DTexture9** piTexture;
// Blend factor of the texture // Blend factor of the texture
float fBlend; float fBlend;
@ -350,6 +353,34 @@ public:
this->m_asMaterials.push_back(info); this->m_asMaterials.push_back(info);
} }
//------------------------------------------------------------------
// set the primary color of the checker pattern background
inline void SetFirstCheckerColor(D3DXVECTOR4 c)
{
this->m_avCheckerColors[0] = c;
}
//------------------------------------------------------------------
// set the secondary color of the checker pattern background
inline void SetSecondCheckerColor(D3DXVECTOR4 c)
{
this->m_avCheckerColors[1] = c;
}
//------------------------------------------------------------------
// get the primary color of the checker pattern background
inline const D3DXVECTOR4* GetFirstCheckerColor() const
{
return &this->m_avCheckerColors[0];
}
//------------------------------------------------------------------
// get the secondary color of the checker pattern background
inline const D3DXVECTOR4* GetSecondCheckerColor() const
{
return &this->m_avCheckerColors[1];
}
private: private:
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -450,6 +481,10 @@ private:
// Current offset (in pixels) of the texture viewer // Current offset (in pixels) of the texture viewer
aiVector2D m_vTextureOffset; aiVector2D m_vTextureOffset;
// Colors used to draw the checker pattern (for the
// texture viewer as background )
D3DXVECTOR4 m_avCheckerColors[2];
}; };
#endif // AV_DISPLAY_H_INCLUDE #endif // AV_DISPLAY_H_INCLUDE

View File

@ -198,7 +198,10 @@ void CLogWindow::WriteLine(const std::string& message)
this->szPlainText.append(message); this->szPlainText.append(message);
this->szPlainText.append("\r\n"); this->szPlainText.append("\r\n");
this->szText.resize(this->szText.length()-1); if (0 != this->szText.length())
{
this->szText.resize(this->szText.length()-1);
}
switch (message.c_str()[0]) switch (message.c_str()[0])
{ {

View File

@ -471,6 +471,11 @@ void CMaterialManager::DeleteMaterial(AssetHelper::MeshHelper* pcIn)
pcIn->piNormalTexture->Release(); pcIn->piNormalTexture->Release();
pcIn->piNormalTexture = NULL; pcIn->piNormalTexture = NULL;
} }
if (pcIn->piShininessTexture)
{
pcIn->piShininessTexture->Release();
pcIn->piShininessTexture = NULL;
}
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
void CMaterialManager::HMtoNMIfNecessary( void CMaterialManager::HMtoNMIfNecessary(
@ -790,6 +795,16 @@ int CMaterialManager::CreateMaterial(
} }
else if (bDefault)pcMesh->eShadingMode = aiShadingMode_Phong; else if (bDefault)pcMesh->eShadingMode = aiShadingMode_Phong;
//
// Shininess strength ------------------------------------------------------
//
if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_SHININESS_STRENGTH,&pcMesh->fSpecularStrength))
{
// assume 1.0 as default shininess strength
pcMesh->fSpecularStrength = 1.0f;
}
aiString szPath; aiString szPath;
// //
@ -1073,7 +1088,10 @@ int CMaterialManager::CreateMaterial(
if (1.0f != pcMesh->fOpacity) if (1.0f != pcMesh->fOpacity)
pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity); pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity);
if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !g_sOptions.bNoSpecular) if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !g_sOptions.bNoSpecular)
{
pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess); pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess);
pcMesh->piEffect->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength);
}
pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor); pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor);
pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor); pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor);
@ -1176,7 +1194,10 @@ int CMaterialManager::SetupMaterial (
if (1.0f != pcMesh->fOpacity) if (1.0f != pcMesh->fOpacity)
pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity); pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity);
if (pcMesh->eShadingMode != aiShadingMode_Gouraud) if (pcMesh->eShadingMode != aiShadingMode_Gouraud)
{
pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess); pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess);
pcMesh->piEffect->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength);
}
pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor); pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor);
pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor); pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor);

View File

@ -50,6 +50,8 @@ class CMaterialManager
{ {
private: private:
friend class CDisplay;
// default constructor // default constructor
CMaterialManager() CMaterialManager()
: m_iShaderCount (0) {} : m_iShaderCount (0) {}

View File

@ -237,6 +237,35 @@ void SaveLightColors()
RegSetValueExA(g_hRegistry,"LightColor2",0,REG_DWORD,(const BYTE*)&g_avLightColors[2],4); RegSetValueExA(g_hRegistry,"LightColor2",0,REG_DWORD,(const BYTE*)&g_avLightColors[2],4);
} }
//-------------------------------------------------------------------------------
// Save the checker pattern colors to the registry
//-------------------------------------------------------------------------------
void SaveCheckerPatternColors()
{
// we have it as float4. save it as binary value --.
RegSetValueExA(g_hRegistry,"CheckerPattern0",0,REG_BINARY,
(const BYTE*)CDisplay::Instance().GetFirstCheckerColor(),
sizeof(D3DXVECTOR3));
RegSetValueExA(g_hRegistry,"CheckerPattern1",0,REG_BINARY,
(const BYTE*)CDisplay::Instance().GetSecondCheckerColor(),
sizeof(D3DXVECTOR3));
}
//-------------------------------------------------------------------------------
// Load the checker pattern colors from the registry
//-------------------------------------------------------------------------------
void LoadCheckerPatternColors()
{
DWORD dwTemp = sizeof(D3DXVECTOR3);
RegQueryValueEx(g_hRegistry,"CheckerPattern0",NULL,NULL,
(BYTE*) /* jep, this is evil */ CDisplay::Instance().GetFirstCheckerColor(),&dwTemp);
RegQueryValueEx(g_hRegistry,"CheckerPattern1",NULL,NULL,
(BYTE*) /* jep, this is evil */ CDisplay::Instance().GetSecondCheckerColor(),&dwTemp);
}
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
// Toggle the "Display Normals" state // Toggle the "Display Normals" state
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
@ -515,7 +544,7 @@ void DisplayColorDialog(D3DCOLOR* pclrResult)
clr.lStructSize = sizeof(CHOOSECOLOR); clr.lStructSize = sizeof(CHOOSECOLOR);
clr.hwndOwner = g_hDlg; clr.hwndOwner = g_hDlg;
clr.Flags = CC_RGBINIT | CC_FULLOPEN; clr.Flags = CC_RGBINIT | CC_FULLOPEN;
clr.rgbResult = RGB(100,100,100); clr.rgbResult = RGB((*pclrResult >> 16) & 0xff,(*pclrResult >> 8) & 0xff,*pclrResult & 0xff);
clr.lpCustColors = g_aclCustomColors; clr.lpCustColors = g_aclCustomColors;
clr.lpfnHook = NULL; clr.lpfnHook = NULL;
clr.lpTemplateName = NULL; clr.lpTemplateName = NULL;
@ -530,6 +559,32 @@ void DisplayColorDialog(D3DCOLOR* pclrResult)
return; return;
} }
//-------------------------------------------------------------------------------
// Let the user choose a color in a windows standard color dialog
//-------------------------------------------------------------------------------
void DisplayColorDialog(D3DXVECTOR4* pclrResult)
{
CHOOSECOLOR clr;
clr.lStructSize = sizeof(CHOOSECOLOR);
clr.hwndOwner = g_hDlg;
clr.Flags = CC_RGBINIT | CC_FULLOPEN;
clr.rgbResult = RGB(clamp<unsigned char>(pclrResult->x * 255.0f),
clamp<unsigned char>(pclrResult->y * 255.0f),
clamp<unsigned char>(pclrResult->z * 255.0f));
clr.lpCustColors = g_aclCustomColors;
clr.lpfnHook = NULL;
clr.lpTemplateName = NULL;
clr.lCustData = NULL;
ChooseColor(&clr);
pclrResult->x = GetRValue(clr.rgbResult) / 255.0f;
pclrResult->y = GetGValue(clr.rgbResult) / 255.0f;
pclrResult->z = GetBValue(clr.rgbResult) / 255.0f;
return;
}
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
// Let the user choose the baclground color for the viewer // Let the user choose the baclground color for the viewer
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
@ -961,7 +1016,7 @@ void InitUI()
SetDlgItemText(g_hDlg,IDC_EFACE,"0"); SetDlgItemText(g_hDlg,IDC_EFACE,"0");
SetDlgItemText(g_hDlg,IDC_EMAT,"0"); SetDlgItemText(g_hDlg,IDC_EMAT,"0");
SetDlgItemText(g_hDlg,IDC_ESHADER,"0"); SetDlgItemText(g_hDlg,IDC_ESHADER,"0");
SetDlgItemText(g_hDlg,IDC_ENODE,"0"); SetDlgItemText(g_hDlg,IDC_ENODEWND,"0");
SetDlgItemText(g_hDlg,IDC_ETEX,"0"); SetDlgItemText(g_hDlg,IDC_ETEX,"0");
SetDlgItemText(g_hDlg,IDC_EMESH,"0"); SetDlgItemText(g_hDlg,IDC_EMESH,"0");
@ -1143,6 +1198,7 @@ void InitUI()
g_sOptions.eDrawMode = RenderOptions::WIREFRAME; g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_CHECKED); CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_CHECKED);
} }
LoadCheckerPatternColors();
return; return;
} }
@ -1263,9 +1319,23 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
if(IDC_LCOLOR1 == pcStruct->CtlID) if(IDC_LCOLOR1 == pcStruct->CtlID)
{ {
unsigned char r = (unsigned char)((g_avLightColors[0] >> 16) & 0xFF); unsigned char r,g,b;
unsigned char g = (unsigned char)((g_avLightColors[0] >> 8) & 0xFF); const char* szText;
unsigned char b = (unsigned char)((g_avLightColors[0]) & 0xFF); if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
r = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->x * 255.0f);
g = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->y * 255.0f);
b = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->z * 255.0f);
szText = "B0";
}
else
{
r = (unsigned char)((g_avLightColors[0] >> 16) & 0xFF);
g = (unsigned char)((g_avLightColors[0] >> 8) & 0xFF);
b = (unsigned char)((g_avLightColors[0]) & 0xFF);
szText = "L0";
}
HBRUSH hbr = CreateSolidBrush(RGB(r,g,b)); HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
FillRect(pcStruct->hDC,&sRect,hbr); FillRect(pcStruct->hDC,&sRect,hbr);
@ -1273,34 +1343,59 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b)); SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
SetBkMode(pcStruct->hDC,TRANSPARENT); SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"L0",2); TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true; bDraw = true;
} }
else if(IDC_LCOLOR2 == pcStruct->CtlID) else if(IDC_LCOLOR2 == pcStruct->CtlID)
{ {
unsigned char r = (unsigned char)((g_avLightColors[1] >> 16) & 0xFF); unsigned char r,g,b;
unsigned char g = (unsigned char)((g_avLightColors[1] >> 8) & 0xFF); const char* szText;
unsigned char b = (unsigned char)((g_avLightColors[1]) & 0xFF); if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
r = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->x * 255.0f);
g = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->y * 255.0f);
b = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->z * 255.0f);
szText = "B1";
}
else
{
r = (unsigned char)((g_avLightColors[1] >> 16) & 0xFF);
g = (unsigned char)((g_avLightColors[1] >> 8) & 0xFF);
b = (unsigned char)((g_avLightColors[1]) & 0xFF);
szText = "L1";
}
HBRUSH hbr = CreateSolidBrush(RGB(r,g,b)); HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
FillRect(pcStruct->hDC,&sRect,hbr); FillRect(pcStruct->hDC,&sRect,hbr);
SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b)); SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
SetBkMode(pcStruct->hDC,TRANSPARENT); SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"L1",2); TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true; bDraw = true;
} }
else if(IDC_LCOLOR3 == pcStruct->CtlID) else if(IDC_LCOLOR3 == pcStruct->CtlID)
{ {
unsigned char r = (unsigned char)((g_avLightColors[2] >> 16) & 0xFF); unsigned char r,g,b;
unsigned char g = (unsigned char)((g_avLightColors[2] >> 8) & 0xFF); const char* szText;
unsigned char b = (unsigned char)((g_avLightColors[2]) & 0xFF); if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
r = g = b = 0;
szText = "-";
}
else
{
r = (unsigned char)((g_avLightColors[2] >> 16) & 0xFF);
g = (unsigned char)((g_avLightColors[2] >> 8) & 0xFF);
b = (unsigned char)((g_avLightColors[2]) & 0xFF);
szText = "A0";
}
HBRUSH hbr = CreateSolidBrush(RGB(r,g,b)); HBRUSH hbr = CreateSolidBrush(RGB(r,g,b));
FillRect(pcStruct->hDC,&sRect,hbr); FillRect(pcStruct->hDC,&sRect,hbr);
SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b)); SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
SetBkMode(pcStruct->hDC,TRANSPARENT); SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"A0",2); TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true; bDraw = true;
} }
// draw the black border around the rects // draw the black border around the rects
@ -1460,14 +1555,8 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
char szFile[MAX_PATH]; char szFile[MAX_PATH];
DragQueryFile(hDrop,0,szFile,sizeof(szFile)); DragQueryFile(hDrop,0,szFile,sizeof(szFile));
if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
{ const char* sz = strrchr(szFile,'.');
// replace the selected texture with the new one ...
CDisplay::Instance().ReplaceCurrentTexture(szFile);
}
else
{
const char* sz = strrchr(szFile,'.');
if (sz && 0 != aiIsExtensionSupported(sz)) if (sz && 0 != aiIsExtensionSupported(sz))
{ {
strcpy(g_szFileName,szFile); strcpy(g_szFileName,szFile);
@ -1477,6 +1566,11 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
UpdateHistory(); UpdateHistory();
SaveHistory(); SaveHistory();
} }
else if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
{
// replace the selected texture with the new one ...
CDisplay::Instance().ReplaceCurrentTexture(szFile);
}
else else
{ {
if (!sz) goto __DRUNKEN_ALIEN_FROM_MARS; if (!sz) goto __DRUNKEN_ALIEN_FROM_MARS;
@ -1535,13 +1629,12 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
else else
{ {
__DRUNKEN_ALIEN_FROM_MARS: __DRUNKEN_ALIEN_FROM_MARS:
CLogDisplay::Instance().AddEntry( CLogDisplay::Instance().AddEntry(
"[ERROR] File extension is not supported. E.T. can read this.", "[ERROR] File extension is not supported. E.T. can read this.",
D3DCOLOR_ARGB(0xFF,0xFF,0,0)); D3DCOLOR_ARGB(0xFF,0xFF,0,0));
} }
} }
} DragFinish(hDrop);
DragFinish(hDrop);
} }
return TRUE; return TRUE;
@ -1713,17 +1806,38 @@ __DRUNKEN_ALIEN_FROM_MARS:
} }
else if (IDC_LCOLOR1 == LOWORD(wParam)) else if (IDC_LCOLOR1 == LOWORD(wParam))
{ {
DisplayColorDialog(&g_avLightColors[0]);
if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
// hey, I'm tired and yes, I KNOW IT IS EVIL!
DisplayColorDialog(const_cast<D3DXVECTOR4*>(CDisplay::Instance().GetFirstCheckerColor()));
SaveCheckerPatternColors();
}
else
{
DisplayColorDialog(&g_avLightColors[0]);
SaveLightColors();
}
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE); InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1)); UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
SaveLightColors();
} }
else if (IDC_LCOLOR2 == LOWORD(wParam)) else if (IDC_LCOLOR2 == LOWORD(wParam))
{ {
DisplayColorDialog(&g_avLightColors[1]); if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
// hey, I'm tired and yes, I KNOW IT IS EVIL!
DisplayColorDialog(const_cast<D3DXVECTOR4*>(CDisplay::Instance().GetSecondCheckerColor()));
SaveCheckerPatternColors();
}
else
{
DisplayColorDialog(&g_avLightColors[1]);
SaveLightColors();
}
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE); InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2)); UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
SaveLightColors();
} }
else if (IDC_LCOLOR3 == LOWORD(wParam)) else if (IDC_LCOLOR3 == LOWORD(wParam))
{ {
@ -1734,9 +1848,20 @@ __DRUNKEN_ALIEN_FROM_MARS:
} }
else if (IDC_LRESET == LOWORD(wParam)) else if (IDC_LRESET == LOWORD(wParam))
{ {
g_avLightColors[0] = D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0xFF); if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
g_avLightColors[1] = D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00); CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
g_avLightColors[2] = D3DCOLOR_ARGB(0xFF,0x05,0x05,0x05); {
CDisplay::Instance().SetFirstCheckerColor(D3DXVECTOR4(0.4f,0.4f,0.4f,1.0f));
CDisplay::Instance().SetSecondCheckerColor(D3DXVECTOR4(0.6f,0.6f,0.6f,1.0f));
SaveCheckerPatternColors();
}
else
{
g_avLightColors[0] = D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0xFF);
g_avLightColors[1] = D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00);
g_avLightColors[2] = D3DCOLOR_ARGB(0xFF,0x05,0x05,0x05);
SaveLightColors();
}
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE); InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1)); UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
@ -1744,7 +1869,6 @@ __DRUNKEN_ALIEN_FROM_MARS:
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2)); UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE); InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3)); UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
SaveLightColors();
} }
else if (IDC_NOSPECULAR == LOWORD(wParam)) else if (IDC_NOSPECULAR == LOWORD(wParam))
{ {

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "GenVertexNormalsProcess.h" #include "GenVertexNormalsProcess.h"
#include "JoinVerticesProcess.h" #include "JoinVerticesProcess.h"
#include "CalcTangentsProcess.h" #include "CalcTangentsProcess.h"
#include "MakeVerboseFormat.h"
namespace AssimpView { namespace AssimpView {
@ -81,83 +82,25 @@ void AssetHelper::SetNormalSet(unsigned int iSet)
if (this->iNormalSet == iSet)return; if (this->iNormalSet == iSet)return;
// we need to build an unique set of vertices for this ... // we need to build an unique set of vertices for this ...
for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)
{ {
aiMesh* pcMesh = this->pcScene->mMeshes[i]; Assimp::MakeVerboseFormatProcess* pcProcess = new Assimp::MakeVerboseFormatProcess();
const unsigned int iNumVerts = pcMesh->mNumFaces*3; pcProcess->Execute(this->pcScene);
delete pcProcess;
aiVector3D* pvPositions = new aiVector3D[iNumVerts]; for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)
aiVector3D* pvNormals = new aiVector3D[iNumVerts];
aiVector3D* pvTangents(NULL), *pvBitangents(NULL);
ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == 4);
ai_assert(AI_MAX_NUMBER_OF_COLOR_SETS == 4);
aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {NULL,NULL,NULL,NULL};
aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {NULL,NULL,NULL,NULL};
unsigned int p = 0;
while (pcMesh->HasTextureCoords(p))
apvTextureCoords[p++] = new aiVector3D[iNumVerts];
p = 0;
while (pcMesh->HasVertexColors(p))
apvColorSets[p++] = new aiColor4D[iNumVerts];
// iterate through all faces and build a clean list
unsigned int iIndex = 0;
for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
{ {
aiFace* pcFace = &pcMesh->mFaces[a]; if (!this->apcMeshes[i]->pvOriginalNormals)
for (unsigned int q = 0; q < 3;++q,++iIndex)
{ {
pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]]; this->apcMeshes[i]->pvOriginalNormals = new aiVector3D[this->pcScene->mMeshes[i]->mNumVertices];
pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]]; memcpy( this->apcMeshes[i]->pvOriginalNormals,this->pcScene->mMeshes[i]->mNormals,
this->pcScene->mMeshes[i]->mNumVertices * sizeof(aiVector3D));
unsigned int p = 0;
while (pcMesh->HasTextureCoords(p))
{
apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
++p;
}
p = 0;
while (pcMesh->HasVertexColors(p))
{
apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
++p;
}
pcFace->mIndices[q] = iIndex;
} }
delete[] this->pcScene->mMeshes[i]->mNormals;
this->pcScene->mMeshes[i]->mNormals = NULL;
} }
// delete the old members
delete[] pcMesh->mVertices;
pcMesh->mVertices = pvPositions;
p = 0;
while (pcMesh->HasTextureCoords(p))
{
delete pcMesh->mTextureCoords[p];
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
++p;
}
p = 0;
while (pcMesh->HasVertexColors(p))
{
delete pcMesh->mColors[p];
pcMesh->mColors[p] = apvColorSets[p];
++p;
}
pcMesh->mNumVertices = iNumVerts;
// keep the pointer to the normals
delete[] pcMesh->mNormals;
pcMesh->mNormals = NULL;
if (!this->apcMeshes[i]->pvOriginalNormals)
this->apcMeshes[i]->pvOriginalNormals = pvNormals;
} }
// now we can start to calculate a new set of normals // now we can start to calculate a new set of normals
if (HARD == iSet) if (HARD == iSet)
{ {
@ -175,7 +118,12 @@ void AssetHelper::SetNormalSet(unsigned int iSet)
{ {
for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i) for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)
{ {
this->pcScene->mMeshes[i]->mNormals = this->apcMeshes[i]->pvOriginalNormals; if (this->apcMeshes[i]->pvOriginalNormals)
{
delete[] this->pcScene->mMeshes[i]->mNormals;
this->pcScene->mMeshes[i]->mNormals = this->apcMeshes[i]->pvOriginalNormals;
this->apcMeshes[i]->pvOriginalNormals = NULL;
}
} }
} }
@ -191,7 +139,7 @@ void AssetHelper::SetNormalSet(unsigned int iSet)
this->iNormalSet = iSet; this->iNormalSet = iSet;
if (g_bWasFlipped && ORIGINAL != iSet) if (g_bWasFlipped)
{ {
// invert all normal vectors // invert all normal vectors
for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i) for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)

View File

@ -473,6 +473,7 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"float SPECULARITY;\n" "float SPECULARITY;\n"
"float SPECULAR_STRENGTH;\n"
"#endif\n" "#endif\n"
"#ifdef AV_OPACITY\n" "#ifdef AV_OPACITY\n"
"float TRANSPARENCY;\n" "float TRANSPARENCY;\n"
@ -746,15 +747,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\n" "#ifndef AV_SKYBOX_LOOKUP\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#else\n" "#else\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SKYBOX_LOOKUP\n" "#endif // !AV_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
@ -817,15 +818,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\n" "#ifndef AV_SKYBOX_LOOKUP\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#else\n" "#else\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SKYBOX_LOOKUP\n" "#endif // !AV_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
@ -858,15 +859,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\n" "#ifndef AV_SKYBOX_LOOKUP\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#else\n" "#else\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SKYBOX_LOOKUP\n" "#endif // !AV_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
@ -921,9 +922,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
"#ifdef AV_AMBIENT_TEXTURE\n" "#ifdef AV_AMBIENT_TEXTURE\n"
@ -976,9 +977,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
"#ifdef AV_AMBIENT_TEXTURE\n" "#ifdef AV_AMBIENT_TEXTURE\n"
@ -1008,9 +1009,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n" "#ifdef AV_SPECULAR_COMPONENT\n"
"#ifdef AV_SPECULAR_TEXTURE\n" "#ifdef AV_SPECULAR_TEXTURE\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#else\n" "#else\n"
"SPECULAR_COLOR.rgb * afLightColor[1].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n" "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
"#endif // !AV_SPECULAR_TEXTURE\n" "#endif // !AV_SPECULAR_TEXTURE\n"
"#endif // !AV_SPECULAR_COMPONENT\n" "#endif // !AV_SPECULAR_COMPONENT\n"
"#ifdef AV_AMBIENT_TEXTURE\n" "#ifdef AV_AMBIENT_TEXTURE\n"

Binary file not shown.

View File

@ -590,9 +590,10 @@ int DeleteAssetData(bool bNoMaterials)
g_pcAsset->apcMeshes[i]->piIB = NULL; g_pcAsset->apcMeshes[i]->piIB = NULL;
} }
//// delete storage eventually allocated to hold a copy // TODO ... unfixed memory leak
//// of the original vertex normals // delete storage eventually allocated to hold a copy
//if (AssetHelper::ORIGINAL != g_pcAsset->iNormalSet) // of the original vertex normals
//if (g_pcAsset->apcMeshes[i]->pvOriginalNormals)
//{ //{
// delete[] g_pcAsset->apcMeshes[i]->pvOriginalNormals; // delete[] g_pcAsset->apcMeshes[i]->pvOriginalNormals;
//} //}
@ -629,6 +630,11 @@ int DeleteAssetData(bool bNoMaterials)
g_pcAsset->apcMeshes[i]->piEmissiveTexture->Release(); g_pcAsset->apcMeshes[i]->piEmissiveTexture->Release();
g_pcAsset->apcMeshes[i]->piEmissiveTexture = NULL; g_pcAsset->apcMeshes[i]->piEmissiveTexture = NULL;
} }
if(g_pcAsset->apcMeshes[i]->piOpacityTexture)
{
g_pcAsset->apcMeshes[i]->piOpacityTexture->Release();
g_pcAsset->apcMeshes[i]->piOpacityTexture = NULL;
}
if(g_pcAsset->apcMeshes[i]->piShininessTexture) if(g_pcAsset->apcMeshes[i]->piShininessTexture)
{ {
g_pcAsset->apcMeshes[i]->piShininessTexture->Release(); g_pcAsset->apcMeshes[i]->piShininessTexture->Release();

View File

@ -160,6 +160,16 @@ INT_PTR CALLBACK HelpDialogProc(HWND hwndDlg,UINT uMsg,
void HandleCommandLine(char* p_szCommand); void HandleCommandLine(char* p_szCommand);
//-------------------------------------------------------------------------------
template <class type, class intype>
type clamp(intype in)
{
// for unsigned types only ...
intype mask = (0x1u << (sizeof(type)*8))-1;
return (type)std::max((intype)0,std::min(in,mask));
}
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
// Position of the cursor relative to the 3ds max' like control circle // Position of the cursor relative to the 3ds max' like control circle
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------

View File

@ -584,6 +584,10 @@
RelativePath="..\..\code\KillNormalsProcess.h" RelativePath="..\..\code\KillNormalsProcess.h"
> >
</File> </File>
<File
RelativePath="..\..\code\MakeVerboseFormat.h"
>
</File>
<File <File
RelativePath="..\..\code\MaterialSystem.h" RelativePath="..\..\code\MaterialSystem.h"
> >
@ -791,6 +795,10 @@
RelativePath="..\..\code\jAssimp\assimp_Texture.h" RelativePath="..\..\code\jAssimp\assimp_Texture.h"
> >
</File> </File>
<File
RelativePath="..\..\code\jAssimp\JNILogger.h"
>
</File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter
@ -844,6 +852,10 @@
RelativePath="..\..\code\KillNormalsProcess.cpp" RelativePath="..\..\code\KillNormalsProcess.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\MakeVerboseFormat.cpp"
>
</File>
<File <File
RelativePath="..\..\code\MaterialSystem.cpp" RelativePath="..\..\code\MaterialSystem.cpp"
> >
@ -979,6 +991,10 @@
RelativePath="..\..\code\jAssimp\JNICalls.cpp" RelativePath="..\..\code\jAssimp\JNICalls.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\jAssimp\JNILogger.cpp"
>
</File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter