FIX: 3DS loader skips TCB keys correctly now.

Further work on 3DS light and camera support + target animation.
Removed obsolete files & directories.
AssimpPCH.h outputs the current build config now (MSVC only)
Simplified foreach workaround
Fixed compilation error in the DLL build

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@258 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-11-30 22:27:20 +00:00
parent e9fc71cc60
commit 9b53b2aa1a
10 changed files with 226 additions and 186 deletions

View File

@ -97,6 +97,16 @@ public:
Blinn = 0x5 Blinn = 0x5
} shadetype3ds; } shadetype3ds;
// Flags for animated keys
enum
{
KEY_USE_TENS = 0x1,
KEY_USE_CONT = 0x2,
KEY_USE_BIAS = 0x4,
KEY_USE_EASE_TO = 0x8,
KEY_USE_EASE_FROM = 0x10
} ;
enum enum
{ {
@ -283,8 +293,20 @@ public:
CHUNK_TRACKLIGHT = 0xB005, CHUNK_TRACKLIGHT = 0xB005,
CHUNK_TRACKLIGTGT = 0xB006, CHUNK_TRACKLIGTGT = 0xB006,
CHUNK_TRACKSPOTL = 0xB007, CHUNK_TRACKSPOTL = 0xB007,
CHUNK_FRAMES = 0xB008 CHUNK_FRAMES = 0xB008,
// ******************************************************************** // ********************************************************************
// light sub-chunks
CHUNK_DL_OFF = 0x4620,
CHUNK_DL_OUTER_RANGE = 0x465A,
CHUNK_DL_INNER_RANGE = 0x4659,
CHUNK_DL_MULTIPLIER = 0x465B,
CHUNK_DL_EXCLUDE = 0x4654,
CHUNK_DL_ATTENUATE = 0x4625,
CHUNK_DL_SPOTLIGHT = 0x4610,
// camera sub-chunks
CHUNK_CAM_RANGES = 0x4720
}; };
}; };
@ -347,9 +369,7 @@ struct Material
mShading(Discreet3DS::Gouraud), mShading(Discreet3DS::Gouraud),
mTransparency (1.0f), mTransparency (1.0f),
mBumpHeight (1.0f), mBumpHeight (1.0f),
mTwoSided (false), mTwoSided (false)
iBakeUVTransform (0),
pcSingleTexture (NULL)
{ {
static int iCnt = 0; static int iCnt = 0;
@ -395,10 +415,6 @@ struct Material
Texture sTexAmbient; Texture sTexAmbient;
//! True if the material must be rendered from two sides //! True if the material must be rendered from two sides
bool mTwoSided; bool mTwoSided;
//! Used internally
unsigned int iBakeUVTransform;
Texture* pcSingleTexture;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -451,6 +467,9 @@ struct aiFloatKey
bool operator < (const aiFloatKey& o) const bool operator < (const aiFloatKey& o) const
{return mTime < o.mTime;} {return mTime < o.mTime;}
bool operator > (const aiFloatKey& o) const
{return mTime < o.mTime;}
#endif #endif
}; };

View File

@ -236,7 +236,6 @@ void Discreet3DSImporter::ParseMainChunk()
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseMainChunk(); return ParseMainChunk();
} }
@ -271,7 +270,6 @@ void Discreet3DSImporter::ParseEditorChunk()
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseEditorChunk(); return ParseEditorChunk();
} }
@ -310,43 +308,32 @@ void Discreet3DSImporter::ParseObjectChunk()
if (is_qnan(mClrAmbient.r)) if (is_qnan(mClrAmbient.r))
{ {
// We failed to read the ambient base color. // We failed to read the ambient base color.
// Set it to black so it won't have affect DefaultLogger::get()->error("3DS: Failed to read ambient base color");
// the rendering mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
mClrAmbient.r = 0.0f;
mClrAmbient.g = 0.0f;
mClrAmbient.b = 0.0f;
} }
break; break;
case Discreet3DS::CHUNK_BIT_MAP: case Discreet3DS::CHUNK_BIT_MAP:
{ {
// Specifies the background image. The string // Specifies the background image. The string should already be
// should already be properly 0 terminated but we // properly 0 terminated but we need to be sure
// need to be sure
unsigned int cnt = 0; unsigned int cnt = 0;
const char* sz = (const char*)stream->GetPtr(); const char* sz = (const char*)stream->GetPtr();
while (stream->GetI1())++cnt; while (stream->GetI1())++cnt;
mBackgroundImage = std::string(sz,cnt); mBackgroundImage = std::string(sz,cnt);
} }
break; break;
case Discreet3DS::CHUNK_BIT_MAP_EXISTS: case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
bHasBG = true; bHasBG = true;
break; break;
case Discreet3DS::CHUNK_MASTER_SCALE: case Discreet3DS::CHUNK_MASTER_SCALE:
// Scene master scaling factor // Scene master scaling factor
mMasterScale = stream->GetF4(); mMasterScale = stream->GetF4();
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseObjectChunk(); return ParseObjectChunk();
} }
@ -386,23 +373,15 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
light->mPosition.y = stream->GetF4(); light->mPosition.y = stream->GetF4();
light->mPosition.z = stream->GetF4(); light->mPosition.z = stream->GetF4();
light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
// Now check for further subchunks (excluding color) // Now check for further subchunks (excluding color)
int8_t* p = stream->GetPtr(); int8_t* p = stream->GetPtr();
ParseLightChunk(); ParseLightChunk();
// Now read the color // The specular light color is identical the the diffuse light
stream->SetPtr(p); // color. The ambient light color is equal to the ambient base
ParseColorChunk(&light->mColorDiffuse,true); // color of the whole scene.
if (is_qnan(light->mColorDiffuse.r))
{
// it could be there is no color subchunk
light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
}
// The specular light color is identical to
// the diffuse light color. The ambient light
// color is equal to the ambient base color of
// the whole scene.
light->mColorSpecular = light->mColorDiffuse; light->mColorSpecular = light->mColorDiffuse;
light->mColorAmbient = mClrAmbient; light->mColorAmbient = mClrAmbient;
@ -421,10 +400,11 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
camera->mName.Set(std::string(name, num)); camera->mName.Set(std::string(name, num));
// The camera position and look-at vector are // Camera position and look-at vector are difficult to handle.
// difficult to handle. Later we'll copy these // If an animation track is given, we must make sure that
// values to the local transformation of the // the track is relative to these values - or , easier
// camera's node. // we must copy the information here to the node matrix of
// the camera's parent in the graph.
// First read the position of the camera // First read the position of the camera
camera->mPosition.x = stream->GetF4(); camera->mPosition.x = stream->GetF4();
@ -435,8 +415,6 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
camera->mLookAt.x = stream->GetF4() - camera->mPosition.x; camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
camera->mLookAt.y = stream->GetF4() - camera->mPosition.y; camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
camera->mLookAt.z = stream->GetF4() - camera->mPosition.z; camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
// We wouldn't need to normalize here, but we do it
camera->mLookAt.Normalize(); camera->mLookAt.Normalize();
// And finally - the camera rotation angle, in // And finally - the camera rotation angle, in
@ -446,13 +424,13 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f); camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
// Read the lense angle // Read the lense angle
// TODO
camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() ); camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
if (camera->mHorizontalFOV < 0.001f)
camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
} }
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseChunk(name,num); return ParseChunk(name,num);
} }
@ -467,32 +445,67 @@ void Discreet3DSImporter::ParseLightChunk()
switch (chunk.Flag) switch (chunk.Flag)
{ {
case Discreet3DS::CHUNK_SPOTLIGHT: case Discreet3DS::CHUNK_SPOTLIGHT:
{ // Now we can be sure that the light is a spot light
// Now we can be sure that the light is a spot light light->mType = aiLightSource_SPOT;
light->mType = aiLightSource_SPOT;
// We wouldn't need to normalize here, but we do it // We wouldn't need to normalize here, but we do it
light->mDirection.x = stream->GetF4() - light->mPosition.x; light->mDirection.x = stream->GetF4() - light->mPosition.x;
light->mDirection.y = stream->GetF4() - light->mPosition.y; light->mDirection.y = stream->GetF4() - light->mPosition.y;
light->mDirection.z = stream->GetF4() - light->mPosition.z; light->mDirection.z = stream->GetF4() - light->mPosition.z;
light->mDirection.Normalize(); light->mDirection.Normalize();
// Now the hotspot and falloff angles - in degrees // Now the hotspot and falloff angles - in degrees
light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() ); light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
light->mAngleOuterCone = AI_DEG_TO_RAD( stream->GetF4() );
// We assume linear attenuation // FIX: the falloff angle is just an offset
light->mAttenuationLinear = 1; light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() );
}
break; break;
// intensity multiplier
case Discreet3DS::CHUNK_DL_MULTIPLIER:
light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
break;
// light color
case Discreet3DS::CHUNK_RGBF:
case Discreet3DS::CHUNK_LINRGBF:
light->mColorDiffuse.r *= stream->GetF4();
light->mColorDiffuse.g *= stream->GetF4();
light->mColorDiffuse.b *= stream->GetF4();
break;
// light attenuation
case Discreet3DS::CHUNK_DL_ATTENUATE:
light->mAttenuationLinear = stream->GetF4();
break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseLightChunk(); return ParseLightChunk();
} }
// ------------------------------------------------------------------------------------------------
void Discreet3DSImporter::ParseCameraChunk()
{
ASSIMP_3DS_BEGIN_CHUNK();
aiCamera* camera = mScene->mCameras.back();
// get chunk type
switch (chunk.Flag)
{
// near and far clip plane
case Discreet3DS::CHUNK_CAM_RANGES:
camera->mClipPlaneNear = stream->GetF4();
camera->mClipPlaneFar = stream->GetF4();
break;
}
ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level
return ParseCameraChunk();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSImporter::ParseKeyframeChunk() void Discreet3DSImporter::ParseKeyframeChunk()
{ {
@ -558,6 +571,34 @@ bool KeyUniqueCompare(const T& first, const T& second)
return first.mTime == second.mTime; return first.mTime == second.mTime;
} }
// ------------------------------------------------------------------------------------------------
void Discreet3DSImporter::SkipTCBInfo()
{
unsigned int flags = stream->GetI2();
if (!flags)
{
// ******************************************************************
// Currently we can't do anything with these values. They occur
// quite rare, so it wouldn't be worth the effort implementing
// them. 3DS ist not really suitable for complex animations,
// so full support is not required.
// ******************************************************************
DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
}
if (flags & Discreet3DS::KEY_USE_TENS)
stream->IncPtr(4);
if (flags & Discreet3DS::KEY_USE_BIAS)
stream->IncPtr(4);
if (flags & Discreet3DS::KEY_USE_CONT)
stream->IncPtr(4);
if (flags & Discreet3DS::KEY_USE_EASE_FROM)
stream->IncPtr(4);
if (flags & Discreet3DS::KEY_USE_EASE_TO)
stream->IncPtr(4);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
{ {
@ -661,15 +702,13 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
case Discreet3DS::CHUNK_TRACKPOS: case Discreet3DS::CHUNK_TRACKPOS:
{ {
stream->IncPtr(10); stream->IncPtr(10);
unsigned int numFrames = stream->GetI2(); const unsigned int numFrames = stream->GetI4();
stream->IncPtr(2);
bool sortKeys = false; bool sortKeys = false;
// This could also be meant as the target position for // This could also be meant as the target position for
// (targeted) lights and cameras // (targeted) lights and cameras
std::vector<aiVectorKey>* l; std::vector<aiVectorKey>* l;
if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent)
Discreet3DS::CHUNK_TRACKLIGTGT == parent)
{ {
l = & mCurrentNode->aTargetPositionKeys; l = & mCurrentNode->aTargetPositionKeys;
} }
@ -678,13 +717,13 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
l->reserve(numFrames); l->reserve(numFrames);
for (unsigned int i = 0; i < numFrames;++i) for (unsigned int i = 0; i < numFrames;++i)
{ {
unsigned int fidx = stream->GetI2(); const unsigned int fidx = stream->GetI4();
// Setup a new position key // Setup a new position key
aiVectorKey v; aiVectorKey v;
v.mTime = (double)fidx; v.mTime = (double)fidx;
stream->IncPtr(4); SkipTCBInfo();
v.mValue.x = stream->GetF4(); v.mValue.x = stream->GetF4();
v.mValue.y = stream->GetF4(); v.mValue.y = stream->GetF4();
v.mValue.z = stream->GetF4(); v.mValue.z = stream->GetF4();
@ -697,12 +736,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
l->push_back(v); l->push_back(v);
} }
// Sort all keys with ascending time values? // Sort all keys with ascending time values and remove duplicates?
if (sortKeys) if (sortKeys)
{ {
std::sort (l->begin(),l->end()); std::stable_sort(l->begin(),l->end());
std::unique (l->begin(),l->end(), l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
std::ptr_fun(&KeyUniqueCompare<aiVectorKey>));
}} }}
break; break;
@ -721,20 +759,18 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys; std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys;
stream->IncPtr(10); stream->IncPtr(10);
unsigned int numFrames = stream->GetI2(); const unsigned int numFrames = stream->GetI4();
l->reserve(numFrames); l->reserve(numFrames);
stream->IncPtr(2);
for (unsigned int i = 0; i < numFrames;++i) for (unsigned int i = 0; i < numFrames;++i)
{ {
unsigned int fidx = stream->GetI2(); const unsigned int fidx = stream->GetI4();
// Setup a new position key // Setup a new position key
aiFloatKey v; aiFloatKey v;
v.mTime = (double)fidx; v.mTime = (double)fidx;
// This is just a single float // This is just a single float
stream->IncPtr(4); SkipTCBInfo();
v.mValue = stream->GetF4(); v.mValue = stream->GetF4();
// Check whether we'll need to sort the keys // Check whether we'll need to sort the keys
@ -745,12 +781,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
l->push_back(v); l->push_back(v);
} }
// Sort all keys with ascending time values? // Sort all keys with ascending time values and remove duplicates?
if (sortKeys) if (sortKeys)
{ {
std::sort (l->begin(),l->end()); std::stable_sort(l->begin(),l->end());
std::unique (l->begin(),l->end(), l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
std::ptr_fun(&KeyUniqueCompare<aiFloatKey>));
}} }}
break; break;
@ -770,8 +805,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
case Discreet3DS::CHUNK_TRACKROTATE: case Discreet3DS::CHUNK_TRACKROTATE:
{ {
stream->IncPtr(10); stream->IncPtr(10);
unsigned int numFrames = stream->GetI2(); const unsigned int numFrames = stream->GetI4();
stream->IncPtr(2);
bool sortKeys = false; bool sortKeys = false;
std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys; std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
@ -779,15 +813,14 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
for (unsigned int i = 0; i < numFrames;++i) for (unsigned int i = 0; i < numFrames;++i)
{ {
unsigned int fidx = stream->GetI2(); const unsigned int fidx = stream->GetI4();
SkipTCBInfo();
stream->IncPtr(4);
aiQuatKey v; aiQuatKey v;
v.mTime = (double)fidx; v.mTime = (double)fidx;
// The rotation keyframe is given as an axis-angle pair // The rotation keyframe is given as an axis-angle pair
float rad = stream->GetF4(); const float rad = stream->GetF4();
aiVector3D axis; aiVector3D axis;
axis.x = stream->GetF4(); axis.x = stream->GetF4();
axis.y = stream->GetF4(); axis.y = stream->GetF4();
@ -806,12 +839,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
// add the new keyframe to the list // add the new keyframe to the list
l->push_back(v); l->push_back(v);
} }
// Sort all keys with ascending time values? // Sort all keys with ascending time values and remove duplicates?
if (sortKeys) if (sortKeys)
{ {
std::sort (l->begin(),l->end()); std::stable_sort(l->begin(),l->end());
std::unique (l->begin(),l->end(), l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
std::ptr_fun(&KeyUniqueCompare<aiQuatKey>));
}} }}
break; break;
@ -820,7 +852,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
case Discreet3DS::CHUNK_TRACKSCALE: case Discreet3DS::CHUNK_TRACKSCALE:
{ {
stream->IncPtr(10); stream->IncPtr(10);
unsigned int numFrames = stream->GetI2(); const unsigned int numFrames = stream->GetI2();
stream->IncPtr(2); stream->IncPtr(2);
bool sortKeys = false; bool sortKeys = false;
@ -829,8 +861,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
for (unsigned int i = 0; i < numFrames;++i) for (unsigned int i = 0; i < numFrames;++i)
{ {
unsigned int fidx = stream->GetI2(); const unsigned int fidx = stream->GetI4();
stream->IncPtr(4); SkipTCBInfo();
// Setup a new key // Setup a new key
aiVectorKey v; aiVectorKey v;
@ -852,18 +884,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
l->push_back(v); l->push_back(v);
} }
// Sort all keys with ascending time values? // Sort all keys with ascending time values and remove duplicates?
if (sortKeys) if (sortKeys)
{ {
std::sort (l->begin(),l->end()); std::stable_sort(l->begin(),l->end());
std::unique (l->begin(),l->end(), l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
std::ptr_fun(&KeyUniqueCompare<aiVectorKey>));
}} }}
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseHierarchyChunk(parent); return ParseHierarchyChunk(parent);
} }
@ -916,12 +946,11 @@ void Discreet3DSImporter::ParseFaceChunk()
{ {
DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz); DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
// ********************************************************* // ******************************************************************
// This material is not known. Ignore this. We will later // This material is not known. Ignore this. We will later
// assign the default material to all faces using *this* // assign the default material to all faces using *this*
// material. Use 0xcdcdcdcd as special value to indicate // material. We use 0xcdcdcdcd as special value to indicate this.
// this. // ******************************************************************
// *********************************************************
} }
// Now continue and read all material indices // Now continue and read all material indices
@ -940,7 +969,6 @@ void Discreet3DSImporter::ParseFaceChunk()
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseFaceChunk(); return ParseFaceChunk();
} }
@ -1062,7 +1090,6 @@ void Discreet3DSImporter::ParseMeshChunk()
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseMeshChunk(); return ParseMeshChunk();
} }
@ -1101,7 +1128,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read DIFFUSE chunk"); DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
pc->r = pc->g = pc->b = 1.0f; pc->r = pc->g = pc->b = 1.0f;
}} }}
break; break;
@ -1114,7 +1141,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read SPECULAR chunk"); DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
pc->r = pc->g = pc->b = 1.0f; pc->r = pc->g = pc->b = 1.0f;
}} }}
break; break;
@ -1127,7 +1154,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read AMBIENT chunk"); DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
pc->r = pc->g = pc->b = 0.0f; pc->r = pc->g = pc->b = 0.0f;
}} }}
break; break;
@ -1140,7 +1167,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read EMISSIVE chunk"); DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
pc->r = pc->g = pc->b = 0.0f; pc->r = pc->g = pc->b = 0.0f;
}} }}
break; break;
@ -1187,11 +1214,10 @@ void Discreet3DSImporter::ParseMaterialChunk()
case Discreet3DS::CHUNK_MAT_SELF_ILPCT: case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
{ // This is the self illumination strength of the material { // This is the self illumination strength of the material
// TODO: need to multiply with emissive base color? float f = ParsePercentageChunk();
float* pcf = &mScene->mMaterials.back().sTexEmissive.mTextureBlend; if (is_qnan(f))f = 0.0f;
*pcf = ParsePercentageChunk(); else f *= (float)0xFFFF / 100.0f;
if (is_qnan(*pcf))*pcf = 0.0f; mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
else *pcf = *pcf * (float)0xFFFF / 100.0f;
} }
break; break;
@ -1221,14 +1247,12 @@ void Discreet3DSImporter::ParseMaterialChunk()
ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive); ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
break; break;
case Discreet3DS::CHUNK_MAT_REFLMAP: case Discreet3DS::CHUNK_MAT_REFLMAP:
// Reflection map - no support in Assimp // Reflection map - no support in Assimp
DefaultLogger::get()->warn("3DS: Found reflection map in file. This is not supported"); DefaultLogger::get()->warn("3DS: Found reflection map in file. This is not supported");
break; break;
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseMaterialChunk(); return ParseMaterialChunk();
} }
@ -1301,7 +1325,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
case Discreet3DS::CHUNK_MAT_MAP_TILING: case Discreet3DS::CHUNK_MAT_MAP_TILING:
{ {
uint16_t iFlags = stream->GetI2(); const uint16_t iFlags = stream->GetI2();
// Get the mapping mode (for both axes) // Get the mapping mode (for both axes)
if (iFlags & 0x2u) if (iFlags & 0x2u)
@ -1317,7 +1341,6 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
}; };
ASSIMP_3DS_END_CHUNK(); ASSIMP_3DS_END_CHUNK();
// recursively continue processing this hierarchy level // recursively continue processing this hierarchy level
return ParseTextureChunk(pcOut); return ParseTextureChunk(pcOut);
} }
@ -1330,28 +1353,22 @@ float Discreet3DSImporter::ParsePercentageChunk()
ReadChunk(&chunk); ReadChunk(&chunk);
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
{
return stream->GetF4(); return stream->GetF4();
}
else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
{
return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF; return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF;
}
return std::numeric_limits<float>::quiet_NaN(); return std::numeric_limits<float>::quiet_NaN();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a color chunk. If a percentage chunk is found instead, it will be converted // Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
// to a grayscale color value void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut, bool acceptPercent)
bool p_bAcceptPercent)
{ {
ai_assert(p_pcOut != NULL); ai_assert(out != NULL);
// error return value // error return value
static const aiColor3D clrError = aiColor3D(std::numeric_limits<float>::quiet_NaN(), const float qnan = std::numeric_limits<float>::quiet_NaN();
std::numeric_limits<float>::quiet_NaN(), static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
std::numeric_limits<float>::quiet_NaN());
Discreet3DS::Chunk chunk; Discreet3DS::Chunk chunk;
ReadChunk(&chunk); ReadChunk(&chunk);
@ -1368,12 +1385,12 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
case Discreet3DS::CHUNK_RGBF: case Discreet3DS::CHUNK_RGBF:
if (sizeof(float) * 3 > diff) if (sizeof(float) * 3 > diff)
{ {
*p_pcOut = clrError; *out = clrError;
return; return;
} }
p_pcOut->r = stream->GetF4(); out->r = stream->GetF4();
p_pcOut->g = stream->GetF4(); out->g = stream->GetF4();
p_pcOut->b = stream->GetF4(); out->b = stream->GetF4();
break; break;
case Discreet3DS::CHUNK_LINRGBB: case Discreet3DS::CHUNK_LINRGBB:
@ -1381,49 +1398,37 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
case Discreet3DS::CHUNK_RGBB: case Discreet3DS::CHUNK_RGBB:
if (sizeof(char) * 3 > diff) if (sizeof(char) * 3 > diff)
{ {
*p_pcOut = clrError; *out = clrError;
return; return;
} }
p_pcOut->r = (float)(uint8_t)stream->GetI1() / 255.0f; out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
p_pcOut->g = (float)(uint8_t)stream->GetI1() / 255.0f; out->g = (float)(uint8_t)stream->GetI1() / 255.0f;
p_pcOut->b = (float)(uint8_t)stream->GetI1() / 255.0f; out->b = (float)(uint8_t)stream->GetI1() / 255.0f;
break; break;
// Percentage chunks: accepted to be compatible with various // Percentage chunks are accepted, too.
// .3ds files with very curious content
case Discreet3DS::CHUNK_PERCENTF: case Discreet3DS::CHUNK_PERCENTF:
if (p_bAcceptPercent && 4 <= diff) if (acceptPercent && 4 <= diff)
{ {
p_pcOut->r = stream->GetF4(); out->g = out->b = out->r = stream->GetF4();
p_pcOut->g = p_pcOut->b = p_pcOut->r;
break; break;
} }
*p_pcOut = clrError; *out = clrError;
return; return;
case Discreet3DS::CHUNK_PERCENTW: case Discreet3DS::CHUNK_PERCENTW:
if (p_bAcceptPercent && 1 <= diff) if (acceptPercent && 1 <= diff)
{ {
p_pcOut->r = (float)(uint8_t)stream->GetI1() / 255.0f; out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
p_pcOut->g = p_pcOut->b = p_pcOut->r;
break; break;
} }
*p_pcOut = clrError; *out = clrError;
return; return;
default: default:
stream->IncPtr(diff);
// skip unknown chunks, hope this won't cause any problems. // Skip unknown chunks, hope this won't cause any problems.
return ParseColorChunk(p_pcOut,p_bAcceptPercent); return ParseColorChunk(out,acceptPercent);
}; };
// Do a gamma correction ... I'm not sure whether this is correct
// or not but I'm too tired now to think of it
if (bGamma)
{
p_pcOut->r = powf(p_pcOut->r, 1.0f / 2.2f);
p_pcOut->g = powf(p_pcOut->g, 1.0f / 2.2f);
p_pcOut->b = powf(p_pcOut->b, 1.0f / 2.2f);
}
return;
} }

View File

@ -176,6 +176,11 @@ protected:
*/ */
void ParseLightChunk(); void ParseLightChunk();
// -------------------------------------------------------------------
/** Parse a camera chunk in the file
*/
void ParseCameraChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a face list chunk in the file /** Parse a face list chunk in the file
*/ */
@ -238,6 +243,11 @@ protected:
*/ */
void CheckIndices(D3DS::Mesh& sMesh); void CheckIndices(D3DS::Mesh& sMesh);
// -------------------------------------------------------------------
/** Skip the TCB info in a track key
*/
void SkipTCBInfo();
protected: protected:
/** Stream to read from */ /** Stream to read from */

View File

@ -44,6 +44,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ASSIMP_INTERNAL_BUILD #define ASSIMP_INTERNAL_BUILD
#ifdef ASSIMP_BUILD_DLL_EXPORT
# if _MSC_VER >= 1400
# pragma message( "AssimpBuild: Building Windows DLL" )
# endif
#endif
// ******************************************************************* // *******************************************************************
// Print detailled memory allocation statistics? In this case we'll // Print detailled memory allocation statistics? In this case we'll
// need to overload all C++ memory management functions. It is assumed // need to overload all C++ memory management functions. It is assumed
@ -56,6 +62,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
void *operator new[] (size_t); void *operator new[] (size_t);
void operator delete[] (void *); void operator delete[] (void *);
# if _MSC_VER >= 1400
# pragma message( "AssimpBuild: Memory tracking enabled" )
# endif
#endif
#if _MSC_VER >= 1400
# ifdef _DEBUG
# pragma message( "AssimpBuild: Debug build" )
# else
# pragma message( "AssimpBuild: Release build" )
# endif
#endif #endif
// ******************************************************************* // *******************************************************************

Binary file not shown.

View File

@ -11,6 +11,15 @@
<childnode /> <childnode />
<childnode /> <childnode />
</node> </node>
<cameras>
<camera up="0,1,0" lookat="0,0,1" fov="45"/>
</cameras>
<lights>
<light diffuse="black" type="spot" phi="5" theta="15"/>
</lights>
<meshes> <meshes>
<mesh id="0"> <mesh id="0">
<meshheader type="MatID, Vertexcount, Facecount, a.s.o." /> <meshheader type="MatID, Vertexcount, Facecount, a.s.o." />

View File

@ -56,28 +56,6 @@ auto_any<typename T::const_iterator> end(T const& t)
return t.end(); return t.end();
} }
// const_iterator
template<typename T>
bool done(auto_any_base const& cur, auto_any_base const& end, T const&)
{
typedef typename T::const_iterator iter_type;
return auto_any_cast<iter_type>(cur) == auto_any_cast<iter_type>(end);
}
template<typename T>
void next(auto_any_base const& cur, T const&)
{
++auto_any_cast<typename T::const_iterator>(cur);
}
template<typename T>
typename T::const_reference deref(auto_any_base const& cur, T const&)
{
return *auto_any_cast<typename T::const_iterator>(cur);
}
// iterator // iterator
template<typename T> template<typename T>
bool done(auto_any_base const& cur, auto_any_base const& end, T&) bool done(auto_any_base const& cur, auto_any_base const& end, T&)

View File

@ -74,6 +74,9 @@ struct aiVectorKey
bool operator < (const aiVectorKey& o) const bool operator < (const aiVectorKey& o) const
{return mTime < o.mTime;} {return mTime < o.mTime;}
bool operator > (const aiVectorKey& o) const
{return mTime > o.mTime;}
#endif #endif
}; };
@ -103,6 +106,8 @@ struct aiQuatKey
bool operator < (const aiQuatKey& o) const bool operator < (const aiQuatKey& o) const
{return mTime < o.mTime;} {return mTime < o.mTime;}
bool operator > (const aiQuatKey& o) const
{return mTime < o.mTime;}
#endif #endif

View File

@ -74,7 +74,7 @@ namespace Assimp
struct aiScene; struct aiScene;
struct aiFileIO; struct aiFileIO;
extern "C" const aiScene* aiImportFileEx( const char*, unsigned int, aiFileIO*); extern "C" ASSIMP_API const aiScene* aiImportFileEx( const char*, unsigned int, aiFileIO*);
namespace Assimp namespace Assimp
{ {

View File

@ -2178,10 +2178,6 @@
RelativePath="..\..\doc\dox.h" RelativePath="..\..\doc\dox.h"
> >
</File> </File>
<File
RelativePath="..\..\doc\ImporterNotes.rtf"
>
</File>
<File <File
RelativePath="..\..\doc\Preamble.txt" RelativePath="..\..\doc\Preamble.txt"
> >