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 */
#include "3DSLoader.h"
#include "MaterialSystem.h"
#include "DefaultLogger.h"
#include "../include/IOStream.h"
#include "../include/IOSystem.h"
@ -98,11 +99,18 @@ void Dot3DSImporter::ReplaceDefaultMaterial()
{
// NOTE: The additional check seems to be necessary,
// some exporters seem to generate invalid data here
if (0xcdcdcdcd == (*a) || (*a) >= this->mScene->mMaterials.size())
if (0xcdcdcdcd == (*a))
{
(*a) = iIndex;
++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())
@ -125,14 +133,17 @@ void Dot3DSImporter::CheckIndices(Dot3DS::Mesh* sMesh)
// check whether all indices are in range
if ((*i).i1 >= sMesh->mPositions.size())
{
DefaultLogger::get()->warn("Face index overflow in 3DS file (#1)");
(*i).i1 = sMesh->mPositions.size()-1;
}
if ((*i).i2 >= sMesh->mPositions.size())
{
DefaultLogger::get()->warn("Face index overflow in 3DS file (#2)");
(*i).i2 = sMesh->mPositions.size()-1;
}
if ((*i).i3 >= sMesh->mPositions.size())
{
DefaultLogger::get()->warn("Face index overflow in 3DS file (#3)");
(*i).i3 = sMesh->mPositions.size()-1;
}
}
@ -155,31 +166,55 @@ void Dot3DSImporter::MakeUnique(Dot3DS::Mesh* sMesh)
vNew2.resize(sMesh->mFaces.size() * 3);
for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
{
uint32_t iTemp1,iTemp2;
// position and texture coordinates
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1];
sMesh->mFaces[i].i1 = iBase++;
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3];
iTemp1 = iBase++;
vNew[iBase] = sMesh->mPositions[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];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3];
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1];
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
{
for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
{
uint32_t iTemp1,iTemp2;
// 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];
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].i1 = iTemp1;
sMesh->mFaces[i].i2 = iTemp2;
// handle the face order ...
/*if (iTemp1 > iTemp2)
{
sMesh->mFaces[i].bFlipped = true;
}*/
}
}
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.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
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);
// 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
mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
@ -231,8 +273,6 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
{
case Dot3DS::Dot3DSFile::Flat:
eShading = aiShadingMode_Flat; break;
case Dot3DS::Dot3DSFile::Phong :
eShading = aiShadingMode_Phong; break;
// I don't know what "Wire" shading should be,
// 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.
// NOTE: I assume the real shader inside 3ds max is an anisotropic
// Phong-Blinn shader, but this is a good approximation too
case Dot3DS::Dot3DSFile::Phong :
eShading = aiShadingMode_Phong; break;
case Dot3DS::Dot3DSFile::Metal :
eShading = aiShadingMode_CookTorrance; break;
}
@ -361,9 +404,8 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
else aiSplit[*a].push_back(iNum);
}
// now generate submeshes
#if 0
bool bFirst = true;
#endif
for (unsigned int p = 0; p < this->mScene->mMaterials.size();++p)
{
if (aiSplit[p].size() != 0)
@ -377,7 +419,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName);
avOutMeshes.push_back(p_pcOut);
#if 0
if (bFirst)
{
p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4();
@ -385,7 +427,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
*((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat;
bFirst = false;
}
#endif
// convert vertices
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].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->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->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->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)
{
const unsigned int iIndex = iArray[i];
#if 0
if (NULL != pcSOut->mMeshes[iIndex]->mColors[1])
{
pcOut->mTransformation = *((aiMatrix4x4*)
@ -514,13 +556,11 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1];
pcSOut->mMeshes[iIndex]->mColors[1] = NULL;
}
#endif
pcOut->mMeshes[i] = iIndex;
}
// NOTE: Not necessary. We can use the given transformation matrix.
// However, we'd need it if we wanted to implement keyframe animation
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0
// build the scaling matrix. Toggle y and z axis
aiMatrix4x4 mS;
@ -536,11 +576,34 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
// build the pivot matrix. Toggle y and z axis
aiMatrix4x4 mP;
mP.a4 = pcIn->vPivot.x;
mP.b4 = pcIn->vPivot.z;
mP.c4 = pcIn->vPivot.y;
mP.a4 = -pcIn->vPivot.x;
mP.b4 = -pcIn->vPivot.z;
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
pcOut->mTransformation = aiMatrix4x4(); // mT * pcIn->mRotation * mS * mP * pcOut->mTransformation.Inverse();
pcOut->mNumChildren = pcIn->mChildren.size();
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
@ -748,6 +811,10 @@ void Dot3DSImporter::BakeScaleNOffset(
{
(*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;
}
const aiVector3D* pvBase = _pvBase;
@ -815,6 +882,9 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
//
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->mChildren = new aiNode* [ pcOut->mNumMeshes ];
@ -827,7 +897,12 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
pcNode->mMeshes = new unsigned int[1];
pcNode->mMeshes[0] = i;
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
pcOut->mRootNode->mChildren[i] = pcNode;
@ -860,6 +935,7 @@ void Dot3DSImporter::ConvertScene(aiScene* pcOut)
this->ConvertMeshes(pcOut);
return;
}
#if 0
// ------------------------------------------------------------------------------------------------
void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
const std::vector<aiVector2D>& p_vIn,
@ -887,3 +963,4 @@ void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
}
return;
}
#endif

View File

@ -59,7 +59,7 @@ void Dot3DSImporter::GenNormals(Dot3DS::Mesh* sMesh)
sMesh->mNormals.resize(sMesh->mPositions.size(),aiVector3D());
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
aiVector3D* pV1 = &sMesh->mPositions[face.i1];

View File

@ -199,6 +199,7 @@ public:
// Specifies the shininess of the material
// followed by percentage chunk
CHUNK_MAT_SHININESS = 0xA040,
CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
// Specifies the shading mode to be used
// followed by a short
@ -304,7 +305,7 @@ public:
/** Helper structure representing a 3ds mesh 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
}
@ -327,9 +328,8 @@ struct Face
//! specifies to which smoothing group the face belongs to
uint32_t iSmoothGroup;
//! Direction the normal vector of the face
//! will be pointing to
bool bDirection;
//! Specifies that the face normal must be flipped
bool bFlipped;
};
// ---------------------------------------------------------------------------
/** Helper structure representing a texture */
@ -376,7 +376,8 @@ struct Material
mTransparency (1.0f),
mBumpHeight (1.0f),
iBakeUVTransform (0),
pcSingleTexture (NULL)
pcSingleTexture (NULL),
mShininessStrength (1.0f)
{
static int iCnt = 0;
std::stringstream ss(mName);
@ -389,6 +390,8 @@ struct Material
aiColor3D mDiffuse;
//! Specular exponent
float mSpecularExponent;
//! Shininess strength, in percent
float mShininessStrength;
//! Specular color of the material
aiColor3D mSpecular;
//! Ambient color of the material
@ -462,9 +465,12 @@ struct Mesh
struct Node
{
Node()
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0
: vScaling(1.0f,1.0f,1.0f)
#endif
{
static int iCnt = 0;
std::stringstream ss(mName);
@ -489,6 +495,7 @@ struct Node
//! Index of the node
int16_t mHierarchyIndex;
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0
aiVector3D vPivot;
aiVector3D vScaling;
@ -502,7 +509,7 @@ struct Node
{
mChildren.push_back(pc);
pc->mParent = this;
pc->mHierarchyPos = this->mHierarchyPos+1;
//pc->mHierarchyPos = this->mHierarchyPos+1;
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 */
#include "3DSLoader.h"
#include "MaterialSystem.h"
#include "DefaultLogger.h"
#include "../include/IOStream.h"
#include "../include/IOSystem.h"
@ -59,7 +60,6 @@ using namespace Assimp;
"specified in the higher-level chunk header." \
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
Dot3DSImporter::Dot3DSImporter()
@ -145,6 +145,7 @@ void Dot3DSImporter::InternReadFile(
this->mMasterScale = 1.0f;
this->mBackgroundImage = "";
this->bHasBG = false;
this->mErrorText = "";
int iRemaining = (unsigned int)fileSize;
this->ParseMainChunk(&iRemaining);
@ -171,30 +172,9 @@ void Dot3DSImporter::InternReadFile(
// found in the file
this->ReplaceDefaultMaterial();
try
{
// 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
// tricky since we'll need to split some meshes into submeshes
@ -205,6 +185,12 @@ void Dot3DSImporter::InternReadFile(
delete[] this->mBuffer;
delete this->mScene;
// check whether an error occured during reading ... set it as warning
if ("" != this->mErrorText)
{
DefaultLogger::get()->warn(this->mErrorText);
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -532,7 +518,7 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
const unsigned char* sz = (unsigned char*)this->mCurrent;
unsigned int iCnt = 0;
uint16_t iHierarchy;
//uint16_t iTemp;
// uint16_t iTemp;
Dot3DS::Node* pcNode;
switch (psChunk->Flag)
{
@ -554,20 +540,28 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
iHierarchy++;
pcNode->mHierarchyPos = iHierarchy;
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
this->mCurrentNode->push_back(pcNode);
this->mLastNodeIndex = iHierarchy;
}
else
{
// need to go back to the specified position in the hierarchy.
this->InverseNodeSearch(pcNode,this->mCurrentNode);
}
this->mLastNodeIndex++;
}
this->mCurrentNode = pcNode;
break;
// (code for keyframe animation. however, this is currently not supported by Assimp)
#if 0
case Dot3DSFile::CHUNK_TRACKPIVOT:
@ -651,42 +645,33 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
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
const float fSin = sinf(-fRadians);
const float fCos = cosf(-fRadians);
const float fOneMinusCos = 1.0f - fCos;
std::swap(vAxis.z,vAxis.y);
vAxis.Normalize();
//vAxis.z *= -1.0f;
//vAxis.Normalize();
aiMatrix4x4 mRot = aiMatrix4x4(
(vAxis.x * vAxis.x) * fOneMinusCos + fCos,
(vAxis.x * vAxis.y) * fOneMinusCos - (vAxis.z * fSin),
(vAxis.x * vAxis.z) * fOneMinusCos + (vAxis.y * fSin),
(vAxis.x * vAxis.y) * fOneMinusCos /*-*/- (vAxis.z * fSin),
(vAxis.x * vAxis.z) * fOneMinusCos /*+*/+ (vAxis.y * fSin),
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.z) * fOneMinusCos - (vAxis.x * fSin),
(vAxis.y * vAxis.z) * fOneMinusCos /*-*/- (vAxis.x * fSin),
0.0f,
(vAxis.z * vAxis.x) * fOneMinusCos - (vAxis.y * fSin),
(vAxis.z * vAxis.y) * fOneMinusCos + (vAxis.x * fSin),
(vAxis.z * vAxis.x) * fOneMinusCos /*-*/- (vAxis.y * fSin),
(vAxis.z * vAxis.y) * fOneMinusCos /*+*/+ (vAxis.x * fSin),
(vAxis.z * vAxis.z) * fOneMinusCos + fCos,
0.0f,0.0f,0.0f,0.0f,1.0f);
//mRot.Transpose();
mRot.Transpose();
// build a chain of concatenated rotation matrix'
// if there are multiple track chunks for the same frame
// (there are some silly files usinf this ...)
if (0 != iNum0)
{
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.z *= vMe.z;
}
else
{
DefaultLogger::get()->warn("Found zero scaling factors. "
"This will be ignored.");
}
this->mCurrent += sizeof(aiVector3D);
}
else this->mCurrent += sizeof(uint32_t) + sizeof(aiVector3D);
}
}
break;
#endif // end keyframe animation code
#endif // 0
};
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
(*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);
}
break;
@ -955,10 +938,10 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
aiMatrix4x4 mMe = mMesh.mMat;
mMe.a1 *= -1.0f;
mMe.a2 *= -1.0f;
mMe.a3 *= -1.0f;
mMe.a4 *= -1.0f;
mInv = mMe * mInv;
mMe.b1 *= -1.0f;
mMe.c1 *= -1.0f;
mMe.d1 *= -1.0f;
mInv = mInv * mMe;
for (register unsigned int i = 0; i < mMesh.mPositions.size();++i)
{
aiVector3D a,c;
@ -1007,8 +990,6 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
sFace.i3 = *((uint16_t*)this->mCurrent);
this->mCurrent += 2*sizeof(uint16_t);
mMesh.mFaces.push_back(sFace);
//if (sFace.i1 < sFace.i2)sFace.bDirection = false;
}
// resize the material array (0xcdcdcdcd marks the
@ -1131,6 +1112,14 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining)
else *pcf *= (float)0xFFFF;
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:
pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend;
*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)
{
p_pcOut->mFaces[q].mIndices[t] = iBase;
p_pcOut->mVertices[iBase] = mesh.mPositions[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

View File

@ -81,24 +81,39 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
{
DefaultLogger::get()->debug("CalcTangentsProcess begin");
bool bHas = false;
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
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
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
// assert() it here.
//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
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
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
@ -229,4 +244,5 @@ void CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
meshBitang[ closeVertices[b] ] = smoothBitangent;
}
}
return true;
}

View File

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

View File

@ -51,7 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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
Logger *DefaultLogger::create(const std::string &name, LogSeverity severity)
{
ai_assert (NULL == m_pLogger);
m_pLogger = new DefaultLogger( name, severity );
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
Logger *DefaultLogger::get()
{
ai_assert (NULL != m_pLogger);
return m_pLogger;
}
@ -92,7 +105,7 @@ void DefaultLogger::kill()
{
ai_assert (NULL != 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 );
// 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 );
m_StreamArray.push_back( pInfo );
}
@ -153,6 +182,12 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{
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 )
@ -166,6 +201,9 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
uiSev &= ( ~Logger::WARN );
if ( severity & Logger::ERR )
uiSev &= ( ~Logger::ERR );
// fix (Aramis)
if ( severity & Logger::DEBUGGING )
uiSev &= ( ~Logger::DEBUGGING );
(*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 <vector>
@ -47,6 +50,39 @@ namespace Assimp
class IOStream;
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
* @brief Default logging implementation. The logger writes into a file.
@ -57,18 +93,39 @@ class DefaultLogger :
public Logger
{
public:
/** @brief Creates the only logging instance
/** @brief Creates a custom logging instance (DefaultLogger)
* @param name Name for logfile
* @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);
/** @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
* @return Only instance
* @return Only instance. This is never null, but it could be a
* NullLogger. Use isNullLogger to check this.
*/
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();
/** @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;
//! only logging instance
static DefaultLogger *m_pLogger;
static Logger *m_pLogger;
static NullLogger s_pNullLogger;
//! Logger severity
LogSeverity m_Severity;
//! Attached streams
@ -123,3 +182,5 @@ private:
// ---------------------------------------------------------------------------
} // Namespace Assimp
#endif // !! AI_DEFAULTLOGGER_H_INCLUDED

View File

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

View File

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

View File

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

View File

@ -244,6 +244,7 @@ void MD2Importer::InternReadFile(
unsigned int iCurrent = 0;
if (0 != this->m_pcHeader->numTexCoords)
{
for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i)
{
// allocate the face
@ -253,10 +254,9 @@ void MD2Importer::InternReadFile(
// copy texture coordinates
// check whether they are different from the previous value at this index.
// 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)
{
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
// validate vertex indices
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
@ -295,6 +295,9 @@ void MD2Importer::InternReadFile(
pcOut->x = u;
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
@ -308,10 +311,9 @@ void MD2Importer::InternReadFile(
// copy texture coordinates
// check whether they are different from the previous value at this index.
// 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)
{
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
// validate vertex indices
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
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->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)
*/
// ---------------------------------------------------------------------------
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 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].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X;
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
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
(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
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
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++;
}

View File

@ -654,6 +654,7 @@ void MDLImporter::InternReadFile_Quake1( )
pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++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->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
pcTriangles++;
}
return;
@ -824,10 +828,9 @@ void MDLImporter::InternReadFile_GameStudio( )
pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices
unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
@ -879,6 +882,9 @@ void MDLImporter::InternReadFile_GameStudio( )
vTexCoords[iCurrent].x = s;
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++;
}
@ -901,10 +907,9 @@ void MDLImporter::InternReadFile_GameStudio( )
pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices
unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
@ -956,6 +961,9 @@ void MDLImporter::InternReadFile_GameStudio( )
vTexCoords[iCurrent].x = s;
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++;
}
}
@ -1384,7 +1392,7 @@ void MDLImporter::InternReadFile_GameStudioA7( )
unsigned int iOutIndex = iTriangle * 3 + c;
// write the output face index
pcFaces[iTriangle].mIndices[c] = iOutIndex;
pcFaces[iTriangle].mIndices[c] = iTriangle * 3 + (2-c);
// swap z and y axis
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;
//DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
return AI_SUCCESS;
}
// ------------------------------------------------------------------------------------------------
@ -77,7 +77,7 @@ aiReturn aiSetTriangleSplitLimit(unsigned int 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;
}
}; //! 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);
// 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.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
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
* Defines the base shininess of the material
* This is the exponent of the phong shading equation.
*/
#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
* Defines the diffuse base color of the material
*/

View File

@ -50,7 +50,7 @@ package assimp;
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public class Animation extends IMappable {
public class Animation extends Mappable {
/**
* 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;
/**
* Created by IntelliJ IDEA.
* User: Alex
* Date: 21.05.2008
* Time: 19:31:28
* To change this template use File | Settings | File Templates.
* Base logging interface. Directly corresponding with the native
* Logger interface
*
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
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)
* @version 1.0
*/
public class Material extends IMappable {
public class Material extends Mappable {
/**
* 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;
import java.lang.ref.Reference;
import java.awt.*;
@ -61,7 +60,7 @@ import java.awt.*;
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public class Mesh extends IMappable {
public class Mesh extends Mappable {
/**
* 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).
* Embedded textures are converted to an array of color values (RGBA).
* <p/>
* Embedded textures in compressed file formats, such as JPEG or DDS
* are NOT supported by jAssimp.
* Compressed textures (textures that are stored in a format like png or jpg)
* are represented by the <code><CompressedTexture/code> class.
*
* @author Aramis (Alexander Gessler)
* @version 1.0
*/
public class Texture extends IMappable {
public class Texture extends Mappable {
private int width = 0;
private int height = 0;
protected int width = 0;
protected int height = 0;
private Color[] data = null;
protected Color[] data = null;
/**
* 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
float fShininess;
// strength of the specular highlight
float fSpecularStrength;
// Stores a pointer to the original normal set of the asset
aiVector3D* pvOriginalNormals;
};

View File

@ -235,7 +235,6 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex];
// update all meshes referencing this material
this->m_pcCurrentTexture->piTexture = piTexture;
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
{
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 = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piDiffuseTexture;
if (!pcMesh->bSharedFX)
{
@ -261,6 +261,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piAmbientTexture->Release();
pcMesh->piAmbientTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piAmbientTexture;
if (!pcMesh->bSharedFX)
{
@ -273,6 +274,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piSpecularTexture->Release();
pcMesh->piSpecularTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piSpecularTexture;
if (!pcMesh->bSharedFX)
{
@ -285,6 +287,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piEmissiveTexture->Release();
pcMesh->piEmissiveTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piEmissiveTexture;
if (!pcMesh->bSharedFX)
{
@ -297,6 +300,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piShininessTexture->Release();
pcMesh->piShininessTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piShininessTexture;
if (!pcMesh->bSharedFX)
{
@ -310,6 +314,9 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piNormalTexture->Release();
pcMesh->piNormalTexture = piTexture;
CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture,
&pcMesh->piNormalTexture,true);
this->m_pcCurrentTexture->piTexture = &pcMesh->piNormalTexture;
if (!pcMesh->bSharedFX)
{
@ -322,6 +329,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
{
pcMesh->piOpacityTexture->Release();
pcMesh->piOpacityTexture = piTexture;
this->m_pcCurrentTexture->piTexture = &pcMesh->piOpacityTexture;
if (!pcMesh->bSharedFX)
{
@ -414,32 +422,32 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType,
bool bIsExtraOpacity = 0 != (iType & 0x40000000);
const char* szType;
IDirect3DTexture9* piTexture;
IDirect3DTexture9** piTexture;
switch (iType)
{
case AI_TEXTYPE_DIFFUSE:
piTexture = g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
szType = "Diffuse";break;
case AI_TEXTYPE_SPECULAR:
piTexture = g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
szType = "Specular";break;
case AI_TEXTYPE_AMBIENT:
piTexture = g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
szType = "Ambient";break;
case AI_TEXTYPE_EMISSIVE:
piTexture = g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
szType = "Emissive";break;
case AI_TEXTYPE_HEIGHT:
piTexture = g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
szType = "HeightMap";break;
case AI_TEXTYPE_NORMALS:
piTexture = g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
szType = "NormalMap";break;
case AI_TEXTYPE_SHININESS:
piTexture = g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
szType = "Shininess";break;
default: // opacity + opacity | mask
piTexture = g_pcAsset->apcMeshes[iMesh]->piOpacityTexture;
piTexture = &g_pcAsset->apcMeshes[iMesh]->piOpacityTexture;
szType = "Opacity";break;
};
if (bIsExtraOpacity)
@ -466,7 +474,7 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType,
uint32_t iData = 0;
DWORD dwSize = 4;
piTexture->GetPrivateData(guidPrivateData,&iData,&dwSize);
(*piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
if (0xFFFFFFFF == iData)
{
@ -583,14 +591,28 @@ 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)
{
// check whether the diffuse texture is not a default texture
// {9785DA94-1D96-426b-B3CB-BADC36347F5E}
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
MaterialInfo info;
@ -785,6 +807,17 @@ int CDisplay::Reset(void)
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()
{
// now ... change the meaning of the statistics fields back
@ -804,6 +837,8 @@ int CDisplay::OnSetupNormalView()
this->m_pcCurrentTexture = NULL;
this->m_pcCurrentNode = NULL;
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg);
return 1;
}
@ -829,6 +864,10 @@ int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew)
this->m_pcCurrentMaterial = pcNew;
this->SetViewMode(VIEWMODE_MATERIAL);
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg);
return 1;
}
//-------------------------------------------------------------------------------
@ -846,6 +885,14 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
"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_vTextureOffset.x = this->m_vTextureOffset.y = 0.0f;
@ -863,7 +910,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
// and fill them with data
D3DSURFACE_DESC sDesc;
pcNew->piTexture->GetLevelDesc(0,&sDesc);
(*pcNew->piTexture)->GetLevelDesc(0,&sDesc);
char szTemp[128];
sprintf(szTemp,"%i",sDesc.Width);
@ -872,7 +919,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
sprintf(szTemp,"%i",sDesc.Height);
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);
sprintf(szTemp,"%i",pcNew->iUV);
@ -899,7 +946,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp);
// NOTE: Format is always ARGB8888 since other formats are
// convert to this format ...
// converted to this format ...
SetWindowText(GetDlgItem(g_hDlg,IDC_EFACE),"ARGB8");
// check whether this is the default texture
@ -912,7 +959,7 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
uint32_t iData = 0;
DWORD dwSize = 4;
pcNew->piTexture->GetPrivateData(guidPrivateData,&iData,&dwSize);
(*pcNew->piTexture)->GetPrivateData(guidPrivateData,&iData,&dwSize);
if (0xFFFFFFFF == iData)
{
@ -922,6 +969,8 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
return 0;
}
}
// redraw the color fields in the UI --- their purpose has possibly changed
UpdateColorFieldsInUI();
UpdateWindow(g_hDlg);
return 1;
}
@ -1047,14 +1096,6 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem)
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)
{
// 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
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)))
{
CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture",
@ -1879,6 +1920,9 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
int CDisplay::RenderPatternBG()
{
if (!g_piPatternEffect)
{
// the pattern effect won't work on ps_2_0 cards
if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3,0))
{
// seems we have not yet compiled this shader.
// and NOW is the best time to do that ...
@ -1905,14 +1949,24 @@ int CDisplay::RenderPatternBG()
piBuffer = NULL;
}
}
else
{
// clear the color buffer in magenta
// (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 );
if (!g_piPatternEffect)
{
return 0;
return 1;
}
}
// clear the depth buffer only
g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,
D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 );
// setup the colors to be used ...
g_piPatternEffect->SetVector("COLOR_ONE",&this->m_avCheckerColors[0]);
g_piPatternEffect->SetVector("COLOR_TWO",&this->m_avCheckerColors[1]);
// setup the shader
UINT dw;
@ -1990,7 +2044,7 @@ int CDisplay::RenderTextureView()
sRect.bottom -= sRect.top;
// 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)
{
@ -2016,7 +2070,7 @@ int CDisplay::RenderTextureView()
// build a rectangle which centers the texture
// scaling is OK, but no stretching
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;};
SVertex as[4];

View File

@ -85,6 +85,9 @@ private:
this->m_aiImageList[2] = 2;
this->m_aiImageList[3] = 3;
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:
@ -112,7 +115,7 @@ public:
struct TextureInfo
{
// texture info
IDirect3DTexture9* piTexture;
IDirect3DTexture9** piTexture;
// Blend factor of the texture
float fBlend;
@ -350,6 +353,34 @@ public:
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:
//------------------------------------------------------------------
@ -450,6 +481,10 @@ private:
// Current offset (in pixels) of the texture viewer
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

View File

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

View File

@ -471,6 +471,11 @@ void CMaterialManager::DeleteMaterial(AssetHelper::MeshHelper* pcIn)
pcIn->piNormalTexture->Release();
pcIn->piNormalTexture = NULL;
}
if (pcIn->piShininessTexture)
{
pcIn->piShininessTexture->Release();
pcIn->piShininessTexture = NULL;
}
}
//-------------------------------------------------------------------------------
void CMaterialManager::HMtoNMIfNecessary(
@ -790,6 +795,16 @@ int CMaterialManager::CreateMaterial(
}
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;
//
@ -1073,7 +1088,10 @@ int CMaterialManager::CreateMaterial(
if (1.0f != pcMesh->fOpacity)
pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity);
if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !g_sOptions.bNoSpecular)
{
pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess);
pcMesh->piEffect->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength);
}
pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor);
pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor);
@ -1176,7 +1194,10 @@ int CMaterialManager::SetupMaterial (
if (1.0f != pcMesh->fOpacity)
pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity);
if (pcMesh->eShadingMode != aiShadingMode_Gouraud)
{
pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess);
pcMesh->piEffect->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength);
}
pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor);
pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor);

View File

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

View File

@ -237,6 +237,35 @@ void SaveLightColors()
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
//-------------------------------------------------------------------------------
@ -515,7 +544,7 @@ void DisplayColorDialog(D3DCOLOR* pclrResult)
clr.lStructSize = sizeof(CHOOSECOLOR);
clr.hwndOwner = g_hDlg;
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.lpfnHook = NULL;
clr.lpTemplateName = NULL;
@ -530,6 +559,32 @@ void DisplayColorDialog(D3DCOLOR* pclrResult)
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
//-------------------------------------------------------------------------------
@ -961,7 +1016,7 @@ void InitUI()
SetDlgItemText(g_hDlg,IDC_EFACE,"0");
SetDlgItemText(g_hDlg,IDC_EMAT,"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_EMESH,"0");
@ -1143,6 +1198,7 @@ void InitUI()
g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_CHECKED);
}
LoadCheckerPatternColors();
return;
}
@ -1263,9 +1319,23 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
if(IDC_LCOLOR1 == pcStruct->CtlID)
{
unsigned char r = (unsigned char)((g_avLightColors[0] >> 16) & 0xFF);
unsigned char g = (unsigned char)((g_avLightColors[0] >> 8) & 0xFF);
unsigned char b = (unsigned char)((g_avLightColors[0]) & 0xFF);
unsigned char r,g,b;
const char* szText;
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));
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));
SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"L0",2);
TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true;
}
else if(IDC_LCOLOR2 == pcStruct->CtlID)
{
unsigned char r = (unsigned char)((g_avLightColors[1] >> 16) & 0xFF);
unsigned char g = (unsigned char)((g_avLightColors[1] >> 8) & 0xFF);
unsigned char b = (unsigned char)((g_avLightColors[1]) & 0xFF);
unsigned char r,g,b;
const char* szText;
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));
FillRect(pcStruct->hDC,&sRect,hbr);
SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"L1",2);
TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true;
}
else if(IDC_LCOLOR3 == pcStruct->CtlID)
{
unsigned char r = (unsigned char)((g_avLightColors[2] >> 16) & 0xFF);
unsigned char g = (unsigned char)((g_avLightColors[2] >> 8) & 0xFF);
unsigned char b = (unsigned char)((g_avLightColors[2]) & 0xFF);
unsigned char r,g,b;
const char* szText;
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));
FillRect(pcStruct->hDC,&sRect,hbr);
SetTextColor(pcStruct->hDC,RGB(0xFF-r,0xFF-g,0xFF-b));
SetBkMode(pcStruct->hDC,TRANSPARENT);
TextOut(pcStruct->hDC,4,1,"A0",2);
TextOut(pcStruct->hDC,4,1,szText,2);
bDraw = true;
}
// draw the black border around the rects
@ -1460,13 +1555,7 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
char szFile[MAX_PATH];
DragQueryFile(hDrop,0,szFile,sizeof(szFile));
if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
{
// replace the selected texture with the new one ...
CDisplay::Instance().ReplaceCurrentTexture(szFile);
}
else
{
const char* sz = strrchr(szFile,'.');
if (sz && 0 != aiIsExtensionSupported(sz))
{
@ -1477,6 +1566,11 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
UpdateHistory();
SaveHistory();
}
else if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode())
{
// replace the selected texture with the new one ...
CDisplay::Instance().ReplaceCurrentTexture(szFile);
}
else
{
if (!sz) goto __DRUNKEN_ALIEN_FROM_MARS;
@ -1540,7 +1634,6 @@ __DRUNKEN_ALIEN_FROM_MARS:
D3DCOLOR_ARGB(0xFF,0xFF,0,0));
}
}
}
DragFinish(hDrop);
}
return TRUE;
@ -1712,18 +1805,39 @@ __DRUNKEN_ALIEN_FROM_MARS:
ToggleMats();
}
else if (IDC_LCOLOR1 == LOWORD(wParam))
{
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);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
SaveLightColors();
}
else if (IDC_LCOLOR2 == LOWORD(wParam))
{
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);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
SaveLightColors();
}
else if (IDC_LCOLOR3 == LOWORD(wParam))
{
@ -1733,10 +1847,21 @@ __DRUNKEN_ALIEN_FROM_MARS:
SaveLightColors();
}
else if (IDC_LRESET == LOWORD(wParam))
{
if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode() ||
CDisplay::VIEWMODE_MATERIAL == CDisplay::Instance().GetViewMode())
{
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);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1));
@ -1744,7 +1869,6 @@ __DRUNKEN_ALIEN_FROM_MARS:
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2));
InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE);
UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3));
SaveLightColors();
}
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 "JoinVerticesProcess.h"
#include "CalcTangentsProcess.h"
#include "MakeVerboseFormat.h"
namespace AssimpView {
@ -81,82 +82,24 @@ void AssetHelper::SetNormalSet(unsigned int iSet)
if (this->iNormalSet == iSet)return;
// we need to build an unique set of vertices for this ...
{
Assimp::MakeVerboseFormatProcess* pcProcess = new Assimp::MakeVerboseFormatProcess();
pcProcess->Execute(this->pcScene);
delete pcProcess;
for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)
{
aiMesh* pcMesh = this->pcScene->mMeshes[i];
const unsigned int iNumVerts = pcMesh->mNumFaces*3;
aiVector3D* pvPositions = new aiVector3D[iNumVerts];
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];
for (unsigned int q = 0; q < 3;++q,++iIndex)
{
pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
pvNormals[iIndex] = pcMesh->mNormals[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;
}
}
// 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;
{
this->apcMeshes[i]->pvOriginalNormals = new aiVector3D[this->pcScene->mMeshes[i]->mNumVertices];
memcpy( this->apcMeshes[i]->pvOriginalNormals,this->pcScene->mMeshes[i]->mNormals,
this->pcScene->mMeshes[i]->mNumVertices * sizeof(aiVector3D));
}
delete[] this->pcScene->mMeshes[i]->mNormals;
this->pcScene->mMeshes[i]->mNormals = NULL;
}
}
// now we can start to calculate a new set of normals
if (HARD == iSet)
@ -175,7 +118,12 @@ void AssetHelper::SetNormalSet(unsigned int iSet)
{
for (unsigned int i = 0; i < this->pcScene->mNumMeshes;++i)
{
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;
if (g_bWasFlipped && ORIGINAL != iSet)
if (g_bWasFlipped)
{
// invert all normal vectors
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"
"float SPECULARITY;\n"
"float SPECULAR_STRENGTH;\n"
"#endif\n"
"#ifdef AV_OPACITY\n"
"float TRANSPARENCY;\n"
@ -746,15 +747,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\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"
"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"
"#else\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"
"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_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n"
@ -817,15 +818,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\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"
"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"
"#else\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"
"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_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n"
@ -858,15 +859,15 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\n"
"#ifndef AV_SKYBOX_LOOKUP\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"
"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"
"#else\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"
"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_SKYBOX_LOOKUP\n"
"#endif // !AV_SPECULAR_COMPONENT\n"
@ -921,9 +922,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\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"
"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_COMPONENT\n"
"#ifdef AV_AMBIENT_TEXTURE\n"
@ -976,9 +977,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\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"
"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_COMPONENT\n"
"#ifdef AV_AMBIENT_TEXTURE\n"
@ -1008,9 +1009,9 @@ std::string g_szMaterialShader = std::string(
"#ifdef AV_SPECULAR_COMPONENT\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"
"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_COMPONENT\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;
}
//// delete storage eventually allocated to hold a copy
//// of the original vertex normals
//if (AssetHelper::ORIGINAL != g_pcAsset->iNormalSet)
// TODO ... unfixed memory leak
// delete storage eventually allocated to hold a copy
// of the original vertex normals
//if (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 = 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)
{
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);
//-------------------------------------------------------------------------------
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
//-------------------------------------------------------------------------------

View File

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