Merge branch 'master' into ios-build-script
* master: Fix missing model error in Irr-instancing closes https://github.com/assimp/assimp/issues/2024: make code more readable. closes https://github.com/assimp/assimp/issues/2019: fix the qt-viewer without export. applied coding conventions added check against the known faces issue_2016 only add material uv mappings if set, ignore when no uvmapping set removed unneccessary pad_i1 field (to prevent unnecessary field read exceptions) Update XFileParser.cpp Update XFileParser.cpp Some FBX files have Null/LimbNode attributes with an empty Properties70 element, where the Element is not NULL, but it's Compound is. The code only checked if the Element itself is NULL, thus causing a DeadlyImportError when trying to instantiate a PropertyTable for an Element that doesn't have a Compound. fix build for independent build dir Some review findings.
This commit is contained in:
@@ -1045,7 +1045,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||
}
|
||||
}
|
||||
}
|
||||
matTexUvMappings.insert(std::make_pair(m, texuv));
|
||||
if (texuv.size()) {
|
||||
matTexUvMappings.insert(std::make_pair(m, texuv));
|
||||
}
|
||||
}
|
||||
|
||||
// collect texture coordinates, they're stored in a separate per-face buffer
|
||||
|
||||
@@ -800,7 +800,6 @@ template <> void Structure::Convert<CustomData>(
|
||||
) const
|
||||
{
|
||||
ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.pad_i1, "pad_i1", db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);
|
||||
|
||||
@@ -432,7 +432,6 @@ CustomData 208
|
||||
struct CustomData : ElemBase {
|
||||
vector<std::shared_ptr<struct CustomDataLayer> > layers;
|
||||
int typemap[42]; // CD_NUMTYPES
|
||||
int pad_i1;
|
||||
int totlayer;
|
||||
int maxlayer;
|
||||
int totsize;
|
||||
|
||||
@@ -272,12 +272,13 @@ struct Node
|
||||
/** Node instances at this node */
|
||||
std::vector<NodeInstance> mNodeInstances;
|
||||
|
||||
/** Rootnodes: Name of primary camera, if any */
|
||||
/** Root-nodes: Name of primary camera, if any */
|
||||
std::string mPrimaryCamera;
|
||||
|
||||
//! Constructor. Begin with a zero parent
|
||||
Node() {
|
||||
mParent = NULL;
|
||||
Node()
|
||||
: mParent( nullptr ){
|
||||
// empty
|
||||
}
|
||||
|
||||
//! Destructor: delete all children subsequently
|
||||
|
||||
@@ -181,26 +181,27 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||
// ... then fill the materials with the now adjusted settings
|
||||
FillMaterials(parser, pScene);
|
||||
|
||||
// Apply unitsize scale calculation
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
||||
0, parser.mUnitSize, 0, 0,
|
||||
0, 0, parser.mUnitSize, 0,
|
||||
0, 0, 0, 1);
|
||||
if( !ignoreUpDirection ) {
|
||||
// Convert to Y_UP, if different orientation
|
||||
if( parser.mUpDirection == ColladaParser::UP_X)
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||
0, -1, 0, 0,
|
||||
1, 0, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||
1, 0, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, -1, 0, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
// Apply unitsize scale calculation
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
||||
0, parser.mUnitSize, 0, 0,
|
||||
0, 0, parser.mUnitSize, 0,
|
||||
0, 0, 0, 1);
|
||||
if( !ignoreUpDirection ) {
|
||||
// Convert to Y_UP, if different orientation
|
||||
if( parser.mUpDirection == ColladaParser::UP_X)
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||
0, -1, 0, 0,
|
||||
1, 0, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||
1, 0, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, -1, 0, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
// store all meshes
|
||||
StoreSceneMeshes( pScene);
|
||||
|
||||
@@ -740,10 +741,6 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||
// create bones if given
|
||||
if( pSrcController && pSrcController->mType == Collada::Skin)
|
||||
{
|
||||
// refuse if the vertex count does not match
|
||||
// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
|
||||
// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
|
||||
|
||||
// resolve references - joint names
|
||||
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
|
||||
const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
|
||||
@@ -971,7 +968,8 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
|
||||
for( size_t b = a+1; b < mAnims.size(); ++b)
|
||||
{
|
||||
aiAnimation* other = mAnims[b];
|
||||
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
|
||||
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration &&
|
||||
other->mTicksPerSecond == templateAnim->mTicksPerSecond )
|
||||
collectedAnimIndices.push_back( b);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ using namespace Assimp::Formatter;
|
||||
// Constructor to be privately used by Importer
|
||||
ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
||||
: mFileName( pFile )
|
||||
, mReader( NULL )
|
||||
, mReader( nullptr )
|
||||
, mDataLibrary()
|
||||
, mAccessorLibrary()
|
||||
, mMeshLibrary()
|
||||
@@ -79,20 +79,20 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
||||
, mLightLibrary()
|
||||
, mCameraLibrary()
|
||||
, mControllerLibrary()
|
||||
, mRootNode( NULL )
|
||||
, mRootNode( nullptr )
|
||||
, mAnims()
|
||||
, mUnitSize( 1.0f )
|
||||
, mUpDirection( UP_Y )
|
||||
, mFormat(FV_1_5_n ) // We assume the newest file format by default
|
||||
{
|
||||
// validate io-handler instance
|
||||
if ( NULL == pIOHandler ) {
|
||||
if (nullptr == pIOHandler ) {
|
||||
throw DeadlyImportError("IOSystem is NULL." );
|
||||
}
|
||||
|
||||
// open the file
|
||||
std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
|
||||
if (file.get() == NULL) {
|
||||
if (file.get() == nullptr) {
|
||||
throw DeadlyImportError( "Failed to open file " + pFile + "." );
|
||||
}
|
||||
|
||||
@@ -363,17 +363,17 @@ void ColladaParser::ReadAnimationClipLibrary()
|
||||
|
||||
void ColladaParser::PostProcessControllers()
|
||||
{
|
||||
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it)
|
||||
{
|
||||
std::string meshId = it->second.mMeshId;
|
||||
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
||||
while(findItr != mControllerLibrary.end()) {
|
||||
meshId = findItr->second.mMeshId;
|
||||
findItr = mControllerLibrary.find(meshId);
|
||||
}
|
||||
std::string meshId;
|
||||
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
|
||||
meshId = it->second.mMeshId;
|
||||
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
||||
while(findItr != mControllerLibrary.end()) {
|
||||
meshId = findItr->second.mMeshId;
|
||||
findItr = mControllerLibrary.find(meshId);
|
||||
}
|
||||
|
||||
it->second.mMeshId = meshId;
|
||||
}
|
||||
it->second.mMeshId = meshId;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -115,7 +115,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
|
||||
}
|
||||
}
|
||||
|
||||
if(!Properties70) {
|
||||
if(!Properties70 || !Properties70->Compound()) {
|
||||
if(!no_warn) {
|
||||
DOMWarning("property table (Properties70) not found",&element);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/importerdesc.h>
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace ::Assimp;
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"Stanford Polygon Library (PLY) Importer",
|
||||
@@ -73,22 +73,20 @@ static const aiImporterDesc desc = {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Internal stuff
|
||||
namespace
|
||||
{
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Checks that property index is within range
|
||||
template <class T>
|
||||
const T &GetProperty(const std::vector<T> &props, int idx)
|
||||
{
|
||||
if (static_cast<size_t>(idx) >= props.size()) {
|
||||
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
|
||||
namespace {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Checks that property index is within range
|
||||
template <class T>
|
||||
inline
|
||||
const T &GetProperty(const std::vector<T> &props, int idx) {
|
||||
if (static_cast<size_t>(idx) >= props.size()) {
|
||||
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
|
||||
}
|
||||
|
||||
return props[idx];
|
||||
}
|
||||
|
||||
return props[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
PLYImporter::PLYImporter()
|
||||
@@ -129,7 +127,7 @@ const aiImporterDesc* PLYImporter::GetInfo() const {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool isBigEndian(const char* szMe) {
|
||||
ai_assert(NULL != szMe);
|
||||
ai_assert(nullptr != szMe);
|
||||
|
||||
// binary_little_endian
|
||||
// binary_big_endian
|
||||
@@ -150,7 +148,7 @@ static bool isBigEndian(const char* szMe) {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
||||
static const std::string mode = "rb";
|
||||
const std::string mode = "rb";
|
||||
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
|
||||
if (!fileStream.get()) {
|
||||
throw DeadlyImportError("Failed to open file " + pFile + ".");
|
||||
@@ -184,7 +182,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
char* szMe = (char*)&this->mBuffer[0];
|
||||
SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
|
||||
|
||||
// determine the format of the file data and construct the aimesh
|
||||
// determine the format of the file data and construct the aiMesh
|
||||
PLY::DOM sPlyDom;
|
||||
this->pcDOM = &sPlyDom;
|
||||
|
||||
@@ -192,7 +190,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
if (TokenMatch(szMe, "ascii", 5)) {
|
||||
SkipLine(szMe, (const char**)&szMe);
|
||||
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
|
||||
if (mGeneratedMesh != NULL) {
|
||||
if (mGeneratedMesh != nullptr) {
|
||||
delete(mGeneratedMesh);
|
||||
mGeneratedMesh = nullptr;
|
||||
}
|
||||
@@ -206,7 +204,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
|
||||
// skip the line, parse the rest of the header and build the DOM
|
||||
if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) {
|
||||
if (mGeneratedMesh != NULL) {
|
||||
if (mGeneratedMesh != nullptr) {
|
||||
delete(mGeneratedMesh);
|
||||
mGeneratedMesh = nullptr;
|
||||
}
|
||||
@@ -215,7 +213,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
|
||||
}
|
||||
} else {
|
||||
if (mGeneratedMesh != NULL) {
|
||||
if (mGeneratedMesh != nullptr) {
|
||||
delete(mGeneratedMesh);
|
||||
mGeneratedMesh = nullptr;
|
||||
}
|
||||
@@ -225,7 +223,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
}
|
||||
} else {
|
||||
AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
|
||||
if (mGeneratedMesh != NULL) {
|
||||
if (mGeneratedMesh != nullptr) {
|
||||
delete(mGeneratedMesh);
|
||||
mGeneratedMesh = nullptr;
|
||||
}
|
||||
@@ -237,13 +235,13 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
//free the file buffer
|
||||
streamedBuffer.close();
|
||||
|
||||
if (mGeneratedMesh == NULL) {
|
||||
if (mGeneratedMesh == nullptr) {
|
||||
throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
|
||||
}
|
||||
|
||||
// if no face list is existing we assume that the vertex
|
||||
// list is containing a list of points
|
||||
bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
|
||||
bool pointsOnly = mGeneratedMesh->mFaces == nullptr ? true : false;
|
||||
if (pointsOnly) {
|
||||
mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT;
|
||||
}
|
||||
@@ -277,8 +275,8 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||
}
|
||||
|
||||
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != instElement);
|
||||
ai_assert(nullptr != pcElement);
|
||||
ai_assert(nullptr != instElement);
|
||||
|
||||
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||
@@ -416,7 +414,7 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||
haveColor = true;
|
||||
}
|
||||
|
||||
// assume 1.0 for the alpha channel ifit is not set
|
||||
// assume 1.0 for the alpha channel if it is not set
|
||||
if (0xFFFFFFFF == aiColors[3]) {
|
||||
cOut.a = 1.0;
|
||||
} else {
|
||||
@@ -481,225 +479,205 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a color component to [0...1]
|
||||
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
|
||||
switch (eType)
|
||||
{
|
||||
case EDT_Float:
|
||||
return val.fFloat;
|
||||
case EDT_Double:
|
||||
return (ai_real)val.fDouble;
|
||||
switch (eType) {
|
||||
case EDT_Float:
|
||||
return val.fFloat;
|
||||
case EDT_Double:
|
||||
return (ai_real)val.fDouble;
|
||||
case EDT_UChar:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFF;
|
||||
case EDT_Char:
|
||||
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
|
||||
case EDT_UShort:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||
case EDT_Short:
|
||||
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
|
||||
case EDT_UInt:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||
case EDT_Int:
|
||||
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case EDT_UChar:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFF;
|
||||
case EDT_Char:
|
||||
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
|
||||
case EDT_UShort:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||
case EDT_Short:
|
||||
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
|
||||
case EDT_UInt:
|
||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||
case EDT_Int:
|
||||
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
||||
default:;
|
||||
};
|
||||
return 0.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Try to extract proper faces from the PLY DOM
|
||||
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
|
||||
{
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != instElement);
|
||||
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement,
|
||||
unsigned int pos) {
|
||||
ai_assert(nullptr != pcElement);
|
||||
ai_assert(nullptr != instElement);
|
||||
|
||||
if (mGeneratedMesh == NULL)
|
||||
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
|
||||
|
||||
bool bOne = false;
|
||||
|
||||
// index of the vertex index list
|
||||
unsigned int iProperty = 0xFFFFFFFF;
|
||||
PLY::EDataType eType = EDT_Char;
|
||||
bool bIsTriStrip = false;
|
||||
|
||||
// index of the material index property
|
||||
//unsigned int iMaterialIndex = 0xFFFFFFFF;
|
||||
//PLY::EDataType eType2 = EDT_Char;
|
||||
|
||||
// texture coordinates
|
||||
unsigned int iTextureCoord = 0xFFFFFFFF;
|
||||
PLY::EDataType eType3 = EDT_Char;
|
||||
|
||||
// face = unique number of vertex indices
|
||||
if (PLY::EEST_Face == pcElement->eSemantic)
|
||||
{
|
||||
unsigned int _a = 0;
|
||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
||||
{
|
||||
if (PLY::EST_VertexIndex == (*a).Semantic)
|
||||
{
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList)
|
||||
continue;
|
||||
|
||||
iProperty = _a;
|
||||
bOne = true;
|
||||
eType = (*a).eType;
|
||||
}
|
||||
/*else if (PLY::EST_MaterialIndex == (*a).Semantic)
|
||||
{
|
||||
if ((*a).bIsList)
|
||||
continue;
|
||||
iMaterialIndex = _a;
|
||||
bOne = true;
|
||||
eType2 = (*a).eType;
|
||||
}*/
|
||||
else if (PLY::EST_TextureCoordinates == (*a).Semantic)
|
||||
{
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList)
|
||||
continue;
|
||||
iTextureCoord = _a;
|
||||
bOne = true;
|
||||
eType3 = (*a).eType;
|
||||
}
|
||||
}
|
||||
}
|
||||
// triangle strip
|
||||
// TODO: triangle strip and material index support???
|
||||
else if (PLY::EEST_TriStrip == pcElement->eSemantic)
|
||||
{
|
||||
unsigned int _a = 0;
|
||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
||||
{
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList)
|
||||
continue;
|
||||
iProperty = _a;
|
||||
bOne = true;
|
||||
bIsTriStrip = true;
|
||||
eType = (*a).eType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether we have at least one per-face information set
|
||||
if (bOne)
|
||||
{
|
||||
if (mGeneratedMesh->mFaces == NULL)
|
||||
{
|
||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||
if (mGeneratedMesh == nullptr) {
|
||||
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
|
||||
}
|
||||
|
||||
if (!bIsTriStrip)
|
||||
{
|
||||
// parse the list of vertex indices
|
||||
if (0xFFFFFFFF != iProperty)
|
||||
{
|
||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
||||
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
||||
bool bOne = false;
|
||||
|
||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
||||
// index of the vertex index list
|
||||
unsigned int iProperty = 0xFFFFFFFF;
|
||||
PLY::EDataType eType = EDT_Char;
|
||||
bool bIsTriStrip = false;
|
||||
|
||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
||||
{
|
||||
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
||||
}
|
||||
}
|
||||
// index of the material index property
|
||||
//unsigned int iMaterialIndex = 0xFFFFFFFF;
|
||||
//PLY::EDataType eType2 = EDT_Char;
|
||||
|
||||
// parse the material index
|
||||
// cannot be handled without processing the whole file first
|
||||
/*if (0xFFFFFFFF != iMaterialIndex)
|
||||
{
|
||||
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
||||
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
||||
}*/
|
||||
// texture coordinates
|
||||
unsigned int iTextureCoord = 0xFFFFFFFF;
|
||||
PLY::EDataType eType3 = EDT_Char;
|
||||
|
||||
if (0xFFFFFFFF != iTextureCoord)
|
||||
{
|
||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
||||
// face = unique number of vertex indices
|
||||
if (PLY::EEST_Face == pcElement->eSemantic) {
|
||||
unsigned int _a = 0;
|
||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||
if (PLY::EST_VertexIndex == (*a).Semantic) {
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//should be 6 coords
|
||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
|
||||
|
||||
if ((iNum / 3) == 2) // X Y coord
|
||||
{
|
||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
||||
{
|
||||
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
||||
if (vindex < mGeneratedMesh->mNumVertices)
|
||||
{
|
||||
if (mGeneratedMesh->mTextureCoords[0] == NULL)
|
||||
{
|
||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
|
||||
if (a % 2 == 0)
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||
else
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
||||
iProperty = _a;
|
||||
bOne = true;
|
||||
eType = (*a).eType;
|
||||
} else if (PLY::EST_TextureCoordinates == (*a).Semantic) {
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList) {
|
||||
continue;
|
||||
}
|
||||
iTextureCoord = _a;
|
||||
bOne = true;
|
||||
eType3 = (*a).eType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // triangle strips
|
||||
{
|
||||
// normally we have only one triangle strip instance where
|
||||
// a value of -1 indicates a restart of the strip
|
||||
bool flip = false;
|
||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
|
||||
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
|
||||
|
||||
int aiTable[2] = { -1, -1 };
|
||||
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
|
||||
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
|
||||
|
||||
if (-1 == p) {
|
||||
// restart the strip ...
|
||||
aiTable[0] = aiTable[1] = -1;
|
||||
flip = false;
|
||||
continue;
|
||||
// triangle strip
|
||||
// TODO: triangle strip and material index support???
|
||||
else if (PLY::EEST_TriStrip == pcElement->eSemantic) {
|
||||
unsigned int _a = 0;
|
||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||
// must be a dynamic list!
|
||||
if (!(*a).bIsList) {
|
||||
continue;
|
||||
}
|
||||
iProperty = _a;
|
||||
bOne = true;
|
||||
bIsTriStrip = true;
|
||||
eType = (*a).eType;
|
||||
break;
|
||||
}
|
||||
if (-1 == aiTable[0]) {
|
||||
aiTable[0] = p;
|
||||
continue;
|
||||
}
|
||||
if (-1 == aiTable[1]) {
|
||||
aiTable[1] = p;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check whether we have at least one per-face information set
|
||||
if (bOne) {
|
||||
if (mGeneratedMesh->mFaces == nullptr) {
|
||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||
}
|
||||
|
||||
if (mGeneratedMesh->mFaces == NULL)
|
||||
if (!bIsTriStrip) {
|
||||
// parse the list of vertex indices
|
||||
if (0xFFFFFFFF != iProperty) {
|
||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
||||
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
||||
|
||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
||||
|
||||
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
||||
}
|
||||
}
|
||||
|
||||
// parse the material index
|
||||
// cannot be handled without processing the whole file first
|
||||
/*if (0xFFFFFFFF != iMaterialIndex)
|
||||
{
|
||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
||||
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
||||
}*/
|
||||
|
||||
if (0xFFFFFFFF != iTextureCoord) {
|
||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
||||
|
||||
//should be 6 coords
|
||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
|
||||
|
||||
if ((iNum / 3) == 2) // X Y coord
|
||||
{
|
||||
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
||||
if (vindex < mGeneratedMesh->mNumVertices) {
|
||||
if (mGeneratedMesh->mTextureCoords[0] == nullptr ) {
|
||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
|
||||
if (a % 2 == 0) {
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||
} else {
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||
}
|
||||
|
||||
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // triangle strips
|
||||
// normally we have only one triangle strip instance where
|
||||
// a value of -1 indicates a restart of the strip
|
||||
bool flip = false;
|
||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
|
||||
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
|
||||
|
||||
int aiTable[2] = { -1, -1 };
|
||||
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
|
||||
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
|
||||
|
||||
if (-1 == p) {
|
||||
// restart the strip ...
|
||||
aiTable[0] = aiTable[1] = -1;
|
||||
flip = false;
|
||||
continue;
|
||||
}
|
||||
if (-1 == aiTable[0]) {
|
||||
aiTable[0] = p;
|
||||
continue;
|
||||
}
|
||||
if (-1 == aiTable[1]) {
|
||||
aiTable[1] = p;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mGeneratedMesh->mFaces == nullptr) {
|
||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||
}
|
||||
|
||||
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
|
||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
||||
|
||||
// every second pass swap the indices.
|
||||
flip = !flip;
|
||||
if ( flip ) {
|
||||
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
||||
}
|
||||
|
||||
aiTable[0] = aiTable[1];
|
||||
aiTable[1] = p;
|
||||
}
|
||||
}
|
||||
|
||||
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
|
||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
||||
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
||||
|
||||
if ((flip = !flip)) {
|
||||
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
||||
}
|
||||
|
||||
aiTable[0] = aiTable[1];
|
||||
aiTable[1] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -332,6 +332,11 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
|
||||
// collect vertex data for indices of this face
|
||||
for( unsigned int d = 0; d < df.mNumIndices; ++d ) {
|
||||
df.mIndices[d] = newIndex;
|
||||
const unsigned int newIdx( pf.mIndices[ d ] );
|
||||
if ( newIdx > sourceMesh->mPositions.size() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
orgPoints[newIndex] = pf.mIndices[d];
|
||||
|
||||
// Position
|
||||
@@ -459,7 +464,7 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
|
||||
nbone->mNodeName.Set( bone->mBoneName);
|
||||
nanim->mChannels[b] = nbone;
|
||||
|
||||
// keyframes are given as combined transformation matrix keys
|
||||
// key-frames are given as combined transformation matrix keys
|
||||
if( !bone->mTrafoKeys.empty() )
|
||||
{
|
||||
nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
|
||||
|
||||
@@ -471,7 +471,10 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
|
||||
unsigned int numIndices = ReadInt();
|
||||
Face& face = pMesh->mPosFaces[a];
|
||||
for (unsigned int b = 0; b < numIndices; ++b) {
|
||||
face.mIndices.push_back( ReadInt() );
|
||||
const int idx( ReadInt() );
|
||||
if ( static_cast<unsigned int>( idx ) <= numVertices ) {
|
||||
face.mIndices.push_back( idx );
|
||||
}
|
||||
}
|
||||
TestForSeparator();
|
||||
}
|
||||
@@ -1293,7 +1296,7 @@ unsigned int XFileParser::ReadBinDWord() {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int XFileParser::ReadInt()
|
||||
{
|
||||
if( mIsBinaryFormat)
|
||||
if( mIsBinaryFormat)
|
||||
{
|
||||
if( mBinaryNumCount == 0 && mEnd - mP >= 2)
|
||||
{
|
||||
@@ -1305,7 +1308,8 @@ unsigned int XFileParser::ReadInt()
|
||||
}
|
||||
|
||||
--mBinaryNumCount;
|
||||
if ( mEnd - mP >= 4) {
|
||||
const size_t len( mEnd - mP );
|
||||
if ( len >= 4) {
|
||||
return ReadBinDWord();
|
||||
} else {
|
||||
mP = mEnd;
|
||||
@@ -1340,6 +1344,7 @@ unsigned int XFileParser::ReadInt()
|
||||
}
|
||||
|
||||
CheckForSeparator();
|
||||
|
||||
return isNegative ? ((unsigned int) -int( number)) : number;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user