Merge branch 'master' into vulcano/export_gltf2_with_roughness_texture

pull/5170/head
Kim Kulling 2023-08-29 15:13:43 +02:00 committed by GitHub
commit e79d105957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 128 additions and 78 deletions

View File

@ -95,6 +95,7 @@ ColladaLoader::ColladaLoader() :
noSkeletonMesh(false), noSkeletonMesh(false),
removeEmptyBones(false), removeEmptyBones(false),
ignoreUpDirection(false), ignoreUpDirection(false),
ignoreUnitSize(false),
useColladaName(false), useColladaName(false),
mNodeNameCounter(0) { mNodeNameCounter(0) {
// empty // empty
@ -122,6 +123,7 @@ void ColladaLoader::SetupProperties(const Importer *pImp) {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0; removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0; ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
ignoreUnitSize = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE, 0) != 0;
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0; useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
} }
@ -170,12 +172,15 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
// ... then fill the materials with the now adjusted settings // ... then fill the materials with the now adjusted settings
FillMaterials(parser, pScene); FillMaterials(parser, pScene);
if (!ignoreUnitSize) {
// Apply unit-size scale calculation // Apply unit-size scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0, 0, 0,
0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0, 0,
0, 0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0,
0, 0, 0, 1); 0, 0, 0, 1);
}
if (!ignoreUpDirection) { if (!ignoreUpDirection) {
// Convert to Y_UP, if different orientation // Convert to Y_UP, if different orientation
if (parser.mUpDirection == ColladaParser::UP_X) { if (parser.mUpDirection == ColladaParser::UP_X) {

View File

@ -239,6 +239,7 @@ protected:
bool noSkeletonMesh; bool noSkeletonMesh;
bool removeEmptyBones; bool removeEmptyBones;
bool ignoreUpDirection; bool ignoreUpDirection;
bool ignoreUnitSize;
bool useColladaName; bool useColladaName;
/** Used by FindNameForNode() to generate unique node names */ /** Used by FindNameForNode() to generate unique node names */

View File

@ -234,7 +234,8 @@ inline void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot);
if (prop.texture && prop.texture->source) { if (prop.texture && prop.texture->source) {
mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength";
mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
} }
} }

View File

@ -1418,9 +1418,8 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX} COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX}
COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX} COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}
) )
ENDIF()
IF(CMAKE_GENERATOR MATCHES "^Visual Studio") IF(GENERATOR_IS_MULTI_CONFIG)
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR} DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS Debug CONFIGURATIONS Debug
@ -1439,6 +1438,11 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
CONFIGURATIONS RelWithDebInfo CONFIGURATIONS RelWithDebInfo
) )
ENDIF() ENDIF()
ELSE()
install(FILES $<TARGET_PDB_FILE:assimp>
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
)
ENDIF()
ENDIF () ENDIF ()
if (ASSIMP_COVERALLS) if (ASSIMP_COVERALLS)

View File

@ -15,8 +15,10 @@ option( DDL_STATIC_LIBRARY "Deprecated, use BUILD_SHARED_LIBS instead."
# for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS # for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS
# https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
if ( DDL_STATIC_LIBRARY ) if ( DDL_STATIC_LIBRARY )
message("Building shared lib.")
set ( build_shared_libs_default OFF ) set ( build_shared_libs_default OFF )
else() else()
message("Building static lib.")
set ( build_shared_libs_default ON ) set ( build_shared_libs_default ON )
endif() endif()
option( DDL_BUILD_SHARED_LIBS "Set to ON to build shared libary of OpenDDL Parser." ${build_shared_libs_default} ) option( DDL_BUILD_SHARED_LIBS "Set to ON to build shared libary of OpenDDL Parser." ${build_shared_libs_default} )
@ -36,6 +38,7 @@ endif()
add_definitions( -D_VARIADIC_MAX=10 ) add_definitions( -D_VARIADIC_MAX=10 )
add_definitions( -DGTEST_HAS_PTHREAD=0 ) add_definitions( -DGTEST_HAS_PTHREAD=0 )
if ( DDL_DEBUG_OUTPUT ) if ( DDL_DEBUG_OUTPUT )
message("Enable debug output.")
add_definitions( -DDDL_DEBUG_HEADER_NAME) add_definitions( -DDDL_DEBUG_HEADER_NAME)
endif() endif()
@ -62,10 +65,12 @@ if (COVERALLS)
include(Coveralls) include(Coveralls)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
message("Enable coveralls.")
endif() endif()
# Include the doc component. # Include the doc component.
if(DDL_DOCUMENTATION) if(DDL_DOCUMENTATION)
message("Generate doxygen documentation.")
find_package(Doxygen REQUIRED) find_package(Doxygen REQUIRED)
CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY ) CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
add_custom_target(doc ALL add_custom_target(doc ALL

View File

@ -5,13 +5,15 @@ The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-pa
Build status Build status
============ ============
Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
Linux build status: [![Build Status](https://travis-ci.com/kimkulling/openddl-parser.svg?branch=master)](https://travis-ci.com/kimkulling/openddl-parser)
Current coverity check status: Current coverity check status:
<a href="https://scan.coverity.com/projects/5606"> <a href="https://scan.coverity.com/projects/5606">
<img alt="Coverity Scan Build Status" <img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5606/badge.svg"/> src="https://scan.coverity.com/projects/5606/badge.svg"/>
</a> </a>
Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls) Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
Get the source code Get the source code
=================== ===================
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command: You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
@ -57,11 +59,11 @@ USE_ODDLPARSER_NS;
int main( int argc, char *argv[] ) { int main( int argc, char *argv[] ) {
if( argc < 3 ) { if( argc < 3 ) {
return 1; return Error;
} }
char *filename( nullptr ); char *filename( nullptr );
if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) { if( 0 == strncmp( FileOption, argv[1], strlen( FileOption ) ) ) {
filename = argv[ 2 ]; filename = argv[ 2 ];
} }
std::cout << "file to import: " << filename << std::endl; std::cout << "file to import: " << filename << std::endl;
@ -73,24 +75,27 @@ int main( int argc, char *argv[] ) {
FILE *fileStream = fopen( filename, "r+" ); FILE *fileStream = fopen( filename, "r+" );
if( NULL == filename ) { if( NULL == filename ) {
std::cerr << "Cannot open file " << filename << std::endl; std::cerr << "Cannot open file " << filename << std::endl;
return 1; return Error;
} }
// obtain file size: // obtain file size:
fseek( fileStream, 0, SEEK_END ); fseek( fileStream, 0, SEEK_END );
const size_t size( ftell( fileStream ) ); const size_t size = ftell( fileStream );
rewind( fileStream ); rewind( fileStream );
if( size > 0 ) { if( size > 0 ) {
char *buffer = new char[ size ]; char *buffer = new char[ size ];
const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) ); const size_t readSize = fread( buffer, sizeof( char ), size, fileStream );
assert( readSize == size ); assert( readSize == size );
// Set the memory buffer
OpenDDLParser theParser; OpenDDLParser theParser;
theParser.setBuffer( buffer, size ); theParser.setBuffer( buffer, size );
const bool result( theParser.parse() ); if( !theParser.parse() ) {
if( !result ) {
std::cerr << "Error while parsing file " << filename << "." << std::endl; std::cerr << "Error while parsing file " << filename << "." << std::endl;
return Error;
} }
} }
return 0; return 0;
} }
@ -106,9 +111,9 @@ theParser.setBuffer( buffer, size );
const bool result( theParser.parse() ); const bool result( theParser.parse() );
if ( result ) { if ( result ) {
DDLNode *root = theParser.getRoot(); DDLNode *root = theParser.getRoot();
DDLNode::DllNodeList childs = root->getChildNodeList(); DDLNode::DllNodeList children = root->getChildNodeList();
for ( size_t i=0; i<childs.size(); i++ ) { for ( size_t i=0; i<children.size(); i++ ) {
DDLNode *child = childs[ i ]; DDLNode *child = children[ i ];
Property *prop = child->getProperty(); // to get properties Property *prop = child->getProperty(); // to get properties
std::string type = child->getType(); // to get the node type std::string type = child->getType(); // to get the node type
Value *values = child->getValue(); // to get the data; Value *values = child->getValue(); // to get the data;

View File

@ -134,9 +134,10 @@ bool OpenDDLExport::writeToStream(const std::string &statement) {
} }
bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
bool success(true);
writeNodeHeader(node, statement); writeNodeHeader(node, statement);
if (node->hasProperties()) { if (node->hasProperties()) {
writeProperties(node, statement); success = writeProperties(node, statement);
} }
writeLineEnd(statement); writeLineEnd(statement);
@ -160,7 +161,7 @@ bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
writeToStream(statement); writeToStream(statement);
return true; return success;
} }
bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) {

View File

@ -30,7 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <sstream> #include <sstream>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> # ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
#endif // _WIN32 #endif // _WIN32
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
@ -71,7 +74,7 @@ const char *getTypeToken(Value::ValueType type) {
return Grammar::PrimitiveTypeToken[(size_t)type]; return Grammar::PrimitiveTypeToken[(size_t)type];
} }
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { static void logInvalidTokenError(const char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
if (callback) { if (callback) {
std::string full(in); std::string full(in);
std::string part(full.substr(0, 50)); std::string part(full.substr(0, 50));
@ -338,6 +341,7 @@ char *OpenDDLParser::parseStructure(char *in, char *end) {
bool error(false); bool error(false);
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (in != end) {
if (*in == *Grammar::OpenBracketToken) { if (*in == *Grammar::OpenBracketToken) {
// loop over all children ( data and nodes ) // loop over all children ( data and nodes )
do { do {
@ -345,14 +349,18 @@ char *OpenDDLParser::parseStructure(char *in, char *end) {
if (in == nullptr) { if (in == nullptr) {
return nullptr; return nullptr;
} }
} while (*in != *Grammar::CloseBracketToken); } while (in != end &&
*in != *Grammar::CloseBracketToken);
if (in != end) {
++in; ++in;
}
} else { } else {
++in; ++in;
logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback); logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback);
error = true; error = true;
return nullptr; return nullptr;
} }
}
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
// pop node from stack after successful parsing // pop node from stack after successful parsing
@ -418,8 +426,8 @@ char *OpenDDLParser::parseStructureBody(char *in, char *end, bool &error) {
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in != '}') { if (in == end || *in != '}') {
logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback); logInvalidTokenError(in == end ? "" : in, std::string(Grammar::CloseBracketToken), m_logCallback);
return nullptr; return nullptr;
} else { } else {
//in++; //in++;
@ -455,7 +463,7 @@ DDLNode *OpenDDLParser::top() {
return nullptr; return nullptr;
} }
DDLNode *top(m_stack.back()); DDLNode *top = m_stack.back();
return top; return top;
} }
@ -647,12 +655,15 @@ char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) {
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
char *start(in); char *start(in);
size_t len(0);
while (!isSeparator(*in) && in != end) { while (!isSeparator(*in) && in != end) {
++in; ++in;
++len;
} }
int res = ::strncmp(Grammar::BoolTrue, start, strlen(Grammar::BoolTrue)); int res = ::strncmp(Grammar::BoolTrue, start, len);
if (0 != res) { if (0 != res) {
res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse)); res = ::strncmp(Grammar::BoolFalse, start, len);
if (0 != res) { if (0 != res) {
*boolean = nullptr; *boolean = nullptr;
return in; return in;
@ -733,7 +744,7 @@ char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating,
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
char *start(in); char *start(in);
while (!isSeparator(*in) && in != end) { while (in != end && !isSeparator(*in)) {
++in; ++in;
} }
@ -838,6 +849,13 @@ char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) {
int value(0); int value(0);
while (pos > 0) { while (pos > 0) {
int v = hex2Decimal(*start); int v = hex2Decimal(*start);
if (v < 0) {
while (isEndofLine(*in)) {
++in;
}
return in;
}
--pos; --pos;
value = (value << 4) | v; value = (value << 4) | v;
++start; ++start;
@ -901,10 +919,10 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == '{') { if (in != end && *in == '{') {
++in; ++in;
Value *current(nullptr), *prev(nullptr); Value *current(nullptr), *prev(nullptr);
while ('}' != *in) { while (in != end && '}' != *in) {
current = nullptr; current = nullptr;
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (Value::ValueType::ddl_ref == type) { if (Value::ValueType::ddl_ref == type) {
@ -962,10 +980,11 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
} }
in = getNextSeparator(in, end); in = getNextSeparator(in, end);
if (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in)) { if (in == end || (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in))) {
break; break;
} }
} }
if (in != end)
++in; ++in;
} }

View File

@ -26,8 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#ifndef _WIN32 #ifndef _WIN32
#include <inttypes.h> #include <inttypes.h>
#endif #endif

View File

@ -40,15 +40,6 @@ struct Identifier;
struct Reference; struct Reference;
struct Property; struct Property;
template <class T>
inline bool isEmbeddedCommentOpenTag(T *in, T *end) {
if (in == '/' && in + 1 == '*') {
return true;
}
return false;
}
/// @brief Utility function to search for the next token or the end of the buffer. /// @brief Utility function to search for the next token or the end of the buffer.
/// @param in [in] The start position in the buffer. /// @param in [in] The start position in the buffer.
/// @param end [in] The end position in the buffer. /// @param end [in] The end position in the buffer.

View File

@ -54,7 +54,9 @@ inline bool isSeparator(T in) {
return false; return false;
} }
static const unsigned char chartype_table[256] = { const size_t CharTableSize = 256;
static const unsigned char chartype_table[CharTableSize] = {
0, 0,
0, 0,
0, 0,
@ -318,6 +320,10 @@ static const unsigned char chartype_table[256] = {
template <class T> template <class T>
inline bool isNumeric(const T in) { inline bool isNumeric(const T in) {
if (static_cast<size_t>(in) >= CharTableSize) {
return '\0';
}
size_t idx = static_cast<size_t>(in); size_t idx = static_cast<size_t>(in);
return idx < sizeof(chartype_table) && (chartype_table[idx] == 1); return idx < sizeof(chartype_table) && (chartype_table[idx] == 1);
} }
@ -433,7 +439,7 @@ inline bool isEndofLine(const T in) {
template <class T> template <class T>
inline static T *getNextSeparator(T *in, T *end) { inline static T *getNextSeparator(T *in, T *end) {
while (!isSeparator(*in) || in == end) { while (in != end && !isSeparator(*in)) {
++in; ++in;
} }
return in; return in;

View File

@ -302,7 +302,9 @@ bool TXmlParser<TNodeType>::parse(IOStream *stream) {
stream->Read(&mData[0], 1, len); stream->Read(&mData[0], 1, len);
mDoc = new pugi::xml_document(); mDoc = new pugi::xml_document();
pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); // load_string assumes native encoding (aka always utf-8 per build options)
//pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
pugi::xml_parse_result parse_result = mDoc->load_buffer(&mData[0], mData.size(), pugi::parse_full);
if (parse_result.status == pugi::status_ok) { if (parse_result.status == pugi::status_ok) {
return true; return true;
} }

View File

@ -1035,6 +1035,15 @@ enum aiComponent
*/ */
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader will ignore the provided unit size.
*
* If this property is set to true, the unit size provided in the file header will
* be ignored and the file will be loaded without scaling the assets.
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE "IMPORT_COLLADA_IGNORE_UNIT_SIZE"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader should use Collada names. /** @brief Specifies whether the Collada loader should use Collada names.
* *

View File

@ -211,6 +211,7 @@ AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
unsigned int idx,aiColor3D& pOut) const { unsigned int idx,aiColor3D& pOut) const {
aiColor4D c; aiColor4D c;
const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c); const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
if (ret == aiReturn_SUCCESS)
pOut = aiColor3D(c.r,c.g,c.b); pOut = aiColor3D(c.r,c.g,c.b);
return ret; return ret;
} }