xml-migration: migrate shared code from irr-loader.

pull/2966/head
Kim Kulling 2020-02-04 20:47:20 +01:00
parent bd2ffc8d58
commit 1a8d5667b6
2 changed files with 212 additions and 325 deletions

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -56,13 +54,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <assimp/material.h>
using namespace Assimp;
using namespace irr;
using namespace irr::io;
// Transformation matrix to convert from Assimp to IRR space
const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
static const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
@ -70,125 +65,94 @@ const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
// ------------------------------------------------------------------------------------------------
// read a property in hexadecimal format (i.e. ffffffff)
void IrrlichtBase::ReadHexProperty (HexProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string( attrib.value() );
} else if (!ASSIMP_stricmp(attrib.name(),"value")) {
// parse the hexadecimal value
out.value = strtoul16(reader->getAttributeValue(i));
out.value = strtoul16(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a decimal property
void IrrlichtBase::ReadIntProperty (IntProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
// parse the ecimal value
out.value = strtol10(reader->getAttributeValue(i));
void IrrlichtBase::ReadIntProperty(IntProperty & out) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.value(),"value")) {
// parse the int value
out.value = strtol10(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a string property
void IrrlichtBase::ReadStringProperty (StringProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
void IrrlichtBase::ReadStringProperty (StringProperty& out) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// simple copy the string
out.value = std::string (reader->getAttributeValue(i));
out.value = std::string(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a boolean property
void IrrlichtBase::ReadBoolProperty (BoolProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")){
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// true or false, case insensitive
out.value = (ASSIMP_stricmp( reader->getAttributeValue(i),
"true") ? false : true);
out.value = (ASSIMP_stricmp(attrib.value(), "true") ? false : true);
}
}
}
// ------------------------------------------------------------------------------------------------
// read a float property
void IrrlichtBase::ReadFloatProperty (FloatProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// just parse the float
out.value = fast_atof( reader->getAttributeValue(i) );
out.value = fast_atof(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a vector property
void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
{
for (int i = 0; i < reader->getAttributeCount();++i)
{
if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
{
out.name = std::string( reader->getAttributeValue(i) );
}
else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
{
void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) {
for (pugi::xml_attribute attrib : mNode.attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// three floats, separated with commas
const char* ptr = reader->getAttributeValue(i);
const char *ptr = attrib.value();
SkipSpaces(&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.x );
SkipSpaces(&ptr);
if (',' != *ptr)
{
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
}
else SkipSpaces(ptr+1,&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y );
SkipSpaces(&ptr);
if (',' != *ptr)
{
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
}
else SkipSpaces(ptr+1,&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z );
}
}
@ -196,22 +160,19 @@ void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
// ------------------------------------------------------------------------------------------------
// Convert a string to a proper aiMappingMode
int ConvertMappingMode(const std::string& mode)
{
if (mode == "texture_clamp_repeat")
{
int ConvertMappingMode(const std::string& mode) {
if (mode == "texture_clamp_repeat") {
return aiTextureMapMode_Wrap;
}
else if (mode == "texture_clamp_mirror")
} else if (mode == "texture_clamp_mirror") {
return aiTextureMapMode_Mirror;
}
return aiTextureMapMode_Clamp;
}
// ------------------------------------------------------------------------------------------------
// Parse a material from the XML file
aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
{
aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) {
aiMaterial* mat = new aiMaterial();
aiColor4D clr;
aiString s;
@ -220,30 +181,17 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
int cnt = 0; // number of used texture channels
unsigned int nd = 0;
// Continue reading from the file
while (reader->read())
{
switch (reader->getNodeType())
{
case EXN_ELEMENT:
// Hex properties
if (!ASSIMP_stricmp(reader->getNodeName(),"color"))
{
for (pugi::xml_node child : mNode.children()) {
if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties
HexProperty prop;
ReadHexProperty(prop);
if (prop.name == "Diffuse")
{
if (prop.name == "Diffuse") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
}
else if (prop.name == "Ambient")
{
} else if (prop.name == "Ambient") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
}
else if (prop.name == "Specular")
{
} else if (prop.name == "Specular") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
}
@ -253,127 +201,78 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// emitted by the described surface. In fact I think
// IRRLICHT ignores this property, too.
#if 0
else if (prop.name == "Emissive")
{
else if (prop.name == "Emissive") {
ColorFromARGBPacked(prop.value,clr);
mat->AddProperty(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
}
#endif
}
// Float properties
else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
{
} else if (!ASSIMP_stricmp(child.name(), "float")) { // Float properties
FloatProperty prop;
ReadFloatProperty(prop);
if (prop.name == "Shininess")
{
if (prop.name == "Shininess") {
mat->AddProperty(&prop.value, 1, AI_MATKEY_SHININESS);
}
}
// Bool properties
else if (!ASSIMP_stricmp(reader->getNodeName(),"bool"))
{
} else if (!ASSIMP_stricmp(child.name(), "bool")) { // Bool properties
BoolProperty prop;
ReadBoolProperty(prop);
if (prop.name == "Wireframe")
{
if (prop.name == "Wireframe") {
int val = (prop.value ? true : false);
mat->AddProperty(&val, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
else if (prop.name == "GouraudShading")
{
int val = (prop.value ? aiShadingMode_Gouraud
: aiShadingMode_NoShading);
} else if (prop.name == "GouraudShading") {
int val = (prop.value ? aiShadingMode_Gouraud : aiShadingMode_NoShading);
mat->AddProperty(&val, 1, AI_MATKEY_SHADING_MODEL);
}
else if (prop.name == "BackfaceCulling")
{
} else if (prop.name == "BackfaceCulling") {
int val = (!prop.value);
mat->AddProperty(&val, 1, AI_MATKEY_TWOSIDED);
}
}
// String properties - textures and texture related properties
else if (!ASSIMP_stricmp(reader->getNodeName(),"texture") ||
!ASSIMP_stricmp(reader->getNodeName(),"enum"))
{
} else if (!ASSIMP_stricmp(child.name(), "texture") ||
!ASSIMP_stricmp(child.name(), "enum")) { // String properties - textures and texture related properties
StringProperty prop;
ReadStringProperty(prop);
if (prop.value.length())
{
if (prop.value.length()) {
// material type (shader)
if (prop.name == "Type")
{
if (prop.value == "solid")
{
if (prop.name == "Type") {
if (prop.value == "solid") {
// default material ...
}
else if (prop.value == "trans_vertex_alpha")
{
} else if (prop.value == "trans_vertex_alpha") {
matFlags = AI_IRRMESH_MAT_trans_vertex_alpha;
}
else if (prop.value == "lightmap")
{
} else if (prop.value == "lightmap") {
matFlags = AI_IRRMESH_MAT_lightmap;
}
else if (prop.value == "solid_2layer")
{
} else if (prop.value == "solid_2layer") {
matFlags = AI_IRRMESH_MAT_solid_2layer;
}
else if (prop.value == "lightmap_m2")
{
} else if (prop.value == "lightmap_m2") {
matFlags = AI_IRRMESH_MAT_lightmap_m2;
}
else if (prop.value == "lightmap_m4")
{
} else if (prop.value == "lightmap_m4") {
matFlags = AI_IRRMESH_MAT_lightmap_m4;
}
else if (prop.value == "lightmap_light")
{
} else if (prop.value == "lightmap_light") {
matFlags = AI_IRRMESH_MAT_lightmap_light;
}
else if (prop.value == "lightmap_light_m2")
{
} else if (prop.value == "lightmap_light_m2") {
matFlags = AI_IRRMESH_MAT_lightmap_light_m2;
}
else if (prop.value == "lightmap_light_m4")
{
} else if (prop.value == "lightmap_light_m4") {
matFlags = AI_IRRMESH_MAT_lightmap_light_m4;
}
else if (prop.value == "lightmap_add")
{
} else if (prop.value == "lightmap_add") {
matFlags = AI_IRRMESH_MAT_lightmap_add;
}
// Normal and parallax maps are treated equally
else if (prop.value == "normalmap_solid" ||
prop.value == "parallaxmap_solid")
{
} else if (prop.value == "normalmap_solid" ||
prop.value == "parallaxmap_solid") { // Normal and parallax maps are treated equally
matFlags = AI_IRRMESH_MAT_normalmap_solid;
}
else if (prop.value == "normalmap_trans_vertex_alpha" ||
prop.value == "parallaxmap_trans_vertex_alpha")
{
} else if (prop.value == "normalmap_trans_vertex_alpha" ||
prop.value == "parallaxmap_trans_vertex_alpha") {
matFlags = AI_IRRMESH_MAT_normalmap_tva;
}
else if (prop.value == "normalmap_trans_add" ||
prop.value == "parallaxmap_trans_add")
{
} else if (prop.value == "normalmap_trans_add" ||
prop.value == "parallaxmap_trans_add") {
matFlags = AI_IRRMESH_MAT_normalmap_ta;
}
else {
} else {
ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value);
}
}
// Up to 4 texture channels are supported
if (prop.name == "Texture1")
{
if (prop.name == "Texture1") {
// Always accept the primary texture channel
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
else if (prop.name == "Texture2" && cnt == 1)
{
} else if (prop.name == "Texture2" && cnt == 1) {
// 2-layer material lightmapped?
if (matFlags & AI_IRRMESH_MAT_lightmap) {
++cnt;
@ -382,9 +281,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
}
// alternatively: normal or parallax mapping
else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) {
} else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) { // alternatively: normal or parallax mapping
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_NORMALS(0));
@ -415,49 +312,39 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
}
// Texture mapping options
if (prop.name == "TextureWrap1" && cnt >= 1)
{
if (prop.name == "TextureWrap1" && cnt >= 1) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
}
else if (prop.name == "TextureWrap2" && cnt >= 2)
{
} else if (prop.name == "TextureWrap2" && cnt >= 2) {
int map = ConvertMappingMode(prop.value);
if (matFlags & AI_IRRMESH_MAT_lightmap) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(0));
}
else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) {
} else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_NORMALS(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_NORMALS(0));
}
else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
} else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(1));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(1));
}
}
else if (prop.name == "TextureWrap3" && cnt >= 3)
{
} else if (prop.name == "TextureWrap3" && cnt >= 3) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd + 1));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd + 1));
}
else if (prop.name == "TextureWrap4" && cnt >= 4)
{
} else if (prop.name == "TextureWrap4" && cnt >= 4) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd + 2));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd + 2));
}
}
}
break;
case EXN_ELEMENT_END:
//break;
/*case EXN_ELEMENT_END:
/* Assume there are no further nested nodes in <material> elements
*/
if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") ||
/* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes"))
// Assume there are no further nested nodes in <material> elements
if ( !ASSIMP_stricmp(reader->getNodeName(),"material") ||
!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
{
// Now process lightmapping flags
// We should have at least one textur to do that ..
@ -492,6 +379,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// GCC complains here ...
break;
}
}*/
}
ASSIMP_LOG_ERROR("IRRMESH: Unexpected end of file. Material is not complete");

View File

@ -15,7 +15,6 @@ struct aiMaterial;
namespace Assimp {
/** @brief Matrix to convert from Assimp to IRR and backwards
*/
extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
@ -80,6 +79,7 @@ protected:
/// XML reader instance
XmlParser mParser;
pugi::xml_node &mNode;
// -------------------------------------------------------------------
/** Parse a material description from the XML
@ -103,15 +103,14 @@ protected:
// ------------------------------------------------------------------------------------------------
// Unpack a hex color, e.g. 0xdcdedfff
inline void ColorFromARGBPacked(uint32_t in, aiColor4D& clr)
{
inline
void ColorFromARGBPacked(uint32_t in, aiColor4D& clr) {
clr.a = ((in >> 24) & 0xff) / 255.f;
clr.r = ((in >> 16) & 0xff) / 255.f;
clr.g = ((in >> 8) & 0xff) / 255.f;
clr.b = ((in ) & 0xff) / 255.f;
}
} // end namespace Assimp
#endif // !! INCLUDED_AI_IRRSHARED_H