vast collada importer improvements, incomplete bmp loading support
parent
715a854199
commit
02c47237a7
|
@ -18,6 +18,7 @@ public:
|
||||||
EPNG = 0,
|
EPNG = 0,
|
||||||
EEXR,
|
EEXR,
|
||||||
ETGA,
|
ETGA,
|
||||||
|
EBMP,
|
||||||
EJPEG
|
EJPEG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,6 +105,9 @@ protected:
|
||||||
|
|
||||||
/// Load a file stored using the TGA file format
|
/// Load a file stored using the TGA file format
|
||||||
void loadTGA(Stream *stream);
|
void loadTGA(Stream *stream);
|
||||||
|
|
||||||
|
/// Load a file stored using the BMP file format
|
||||||
|
void loadBMP(Stream *stream);
|
||||||
|
|
||||||
/// Load a file stored using the JPEG file format
|
/// Load a file stored using the JPEG file format
|
||||||
void loadJPEG(Stream *stream);
|
void loadJPEG(Stream *stream);
|
||||||
|
|
|
@ -111,6 +111,9 @@ public:
|
||||||
/// Return the logger's formatter implementation
|
/// Return the logger's formatter implementation
|
||||||
inline Formatter *getFormatter() { return m_formatter; }
|
inline Formatter *getFormatter() { return m_formatter; }
|
||||||
|
|
||||||
|
/// Return the number of warnings reported so far
|
||||||
|
inline size_t getWarningCount() const { return m_warningCount; }
|
||||||
|
|
||||||
/// Initialize logging
|
/// Initialize logging
|
||||||
static void staticInitialization();
|
static void staticInitialization();
|
||||||
|
|
||||||
|
@ -126,6 +129,7 @@ protected:
|
||||||
ref<Formatter> m_formatter;
|
ref<Formatter> m_formatter;
|
||||||
ref<Mutex> m_mutex;
|
ref<Mutex> m_mutex;
|
||||||
std::vector<Appender *> m_appenders;
|
std::vector<Appender *> m_appenders;
|
||||||
|
size_t m_warningCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
|
@ -101,18 +101,22 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
||||||
result->typeToOffset.resize(ELast);
|
result->typeToOffset.resize(ELast);
|
||||||
for (int i=0; i<ELast; ++i)
|
for (int i=0; i<ELast; ++i)
|
||||||
result->typeToOffset[i] = -1;
|
result->typeToOffset[i] = -1;
|
||||||
|
int vertInputIndex = 0;
|
||||||
|
|
||||||
for (size_t i=0; i<inputs.getCount(); ++i) {
|
for (size_t i=0; i<inputs.getCount(); ++i) {
|
||||||
int offset = (int) inputs[i]->getOffset();
|
int offset = (int) inputs[i]->getOffset();
|
||||||
daeURI &sourceRef = inputs[i]->getSource();
|
daeURI &sourceRef = inputs[i]->getSource();
|
||||||
sourceRef.resolveElement();
|
sourceRef.resolveElement();
|
||||||
domSource *source = daeSafeCast<domSource>(sourceRef.getElement());
|
domSource *source = daeSafeCast<domSource>(sourceRef.getElement());
|
||||||
|
std::string semantic = inputs[i]->getSemantic();
|
||||||
|
|
||||||
if (!strcmp(inputs[i]->getSemantic(), "VERTEX")) {
|
if (semantic == "VERTEX") {
|
||||||
SAssert(vertInputs.getCount() == 1);
|
sourceRef = vertInputs[vertInputIndex]->getSource();
|
||||||
sourceRef = vertInputs[0]->getSource();
|
|
||||||
sourceRef.resolveElement();
|
sourceRef.resolveElement();
|
||||||
source = daeSafeCast<domSource>(sourceRef.getElement());
|
source = daeSafeCast<domSource>(sourceRef.getElement());
|
||||||
|
semantic = vertInputs[vertInputIndex]->getSemantic();
|
||||||
|
if (++vertInputIndex < (int) vertInputs.getCount())
|
||||||
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
domListOfFloats &floatArray = source->getFloat_array()->getValue();
|
domListOfFloats &floatArray = source->getFloat_array()->getValue();
|
||||||
|
@ -128,14 +132,13 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
||||||
SAssert(nParams <= 4);
|
SAssert(nParams <= 4);
|
||||||
|
|
||||||
Vec4 *target = new Vec4[size];
|
Vec4 *target = new Vec4[size];
|
||||||
for (int j=0; j<size; ++j) {
|
for (int j=0; j<size; ++j)
|
||||||
for (int k=0; k<nParams; ++k)
|
for (int k=0; k<nParams; ++k)
|
||||||
target[j][k] = (Float) floatArray[j*stride+k];
|
target[j][k] = (Float) floatArray[j*stride+k];
|
||||||
}
|
|
||||||
|
|
||||||
result->data[offset] = target;
|
result->data[offset] = target;
|
||||||
|
|
||||||
if (!strcmp(inputs[i]->getSemantic(), "VERTEX")) {
|
if (semantic == "POSITION") {
|
||||||
SAssert(accessor->getStride() == 3);
|
SAssert(accessor->getStride() == 3);
|
||||||
SAssert(result->typeToOffset[EPosition] == -1);
|
SAssert(result->typeToOffset[EPosition] == -1);
|
||||||
result->offsetToType[offset] = EPosition;
|
result->offsetToType[offset] = EPosition;
|
||||||
|
@ -143,28 +146,28 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
||||||
result->glPos = new GLdouble[3*size];
|
result->glPos = new GLdouble[3*size];
|
||||||
for (int k=0; k<3*size; ++k)
|
for (int k=0; k<3*size; ++k)
|
||||||
result->glPos[k] = floatArray[k];
|
result->glPos[k] = floatArray[k];
|
||||||
} else if (!strcmp(inputs[i]->getSemantic(), "NORMAL")) {
|
} else if (semantic == "NORMAL") {
|
||||||
SAssert(accessor->getStride() == 3);
|
SAssert(accessor->getStride() == 3);
|
||||||
SAssert(result->typeToOffset[ENormal] == -1);
|
SAssert(result->typeToOffset[ENormal] == -1);
|
||||||
result->hasNormals = true;
|
result->hasNormals = true;
|
||||||
result->offsetToType[offset] = ENormal;
|
result->offsetToType[offset] = ENormal;
|
||||||
result->typeToOffset[ENormal] = offset;
|
result->typeToOffset[ENormal] = offset;
|
||||||
} else if (!strcmp(inputs[i]->getSemantic(), "TEXCOORD")) {
|
} else if (semantic == "TEXCOORD") {
|
||||||
SAssert(accessor->getStride() == 2 || accessor->getStride() == 3);
|
SAssert(accessor->getStride() == 2 || accessor->getStride() == 3);
|
||||||
if (result->typeToOffset[EUV] == -1) {
|
if (result->typeToOffset[EUV] == -1) {
|
||||||
result->hasUVs = true;
|
result->hasUVs = true;
|
||||||
result->offsetToType[offset] = EUV;
|
result->offsetToType[offset] = EUV;
|
||||||
result->typeToOffset[EUV] = offset;
|
result->typeToOffset[EUV] = offset;
|
||||||
} else {
|
} else {
|
||||||
SLog(EWarn, "Found multiple texture coordinate records - ignoring!");
|
SLog(EWarn, "Found multiple sets of texture coordinates - ignoring!");
|
||||||
}
|
}
|
||||||
} else if (!strcmp(inputs[i]->getSemantic(), "COLOR")) {
|
} else if (semantic == "COLOR") {
|
||||||
SLog(EWarn, "Found per-vertex colors - ignoring. Please bake into a texture (Lighting/shading -> Batch Bake in Maya)");
|
SLog(EWarn, "Found per-vertex colors - ignoring. Please bake into a texture "
|
||||||
|
"(Lighting/shading -> Batch Bake in Maya)");
|
||||||
result->offsetToType[offset] = EVertexColors;
|
result->offsetToType[offset] = EVertexColors;
|
||||||
result->typeToOffset[EVertexColors] = offset;
|
result->typeToOffset[EVertexColors] = offset;
|
||||||
} else {
|
} else {
|
||||||
SLog(EError, "Encountered an unknown source semantic: %s",
|
SLog(EError, "Encountered an unknown source semantic: %s", semantic.c_str());
|
||||||
inputs[i]->getSemantic());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SAssert(result->typeToOffset[EPosition] != -1);
|
SAssert(result->typeToOffset[EPosition] != -1);
|
||||||
|
@ -272,20 +275,21 @@ void writeGeometry(std::string id, int geomIndex, std::string matID, Transform t
|
||||||
os << "\t</shape>" << endl << endl;
|
os << "\t</shape>" << endl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadGeometry(std::string nodeName, Transform transform, std::ostream &os, domGeometry &geom,
|
void loadGeometry(std::string prefixName, Transform transform, std::ostream &os, domGeometry &geom,
|
||||||
StringMap &matLookupTable, const std::string &meshesDir) {
|
StringMap &matLookupTable, const std::string &meshesDir) {
|
||||||
std::string geomName;
|
std::string identifier;
|
||||||
if (geom.getName() != NULL) {
|
if (geom.getId() != NULL) {
|
||||||
geomName = geom.getName();
|
identifier = geom.getId();
|
||||||
} else {
|
} else {
|
||||||
if (geom.getId() != NULL) {
|
if (geom.getName() != NULL) {
|
||||||
geomName = geom.getId();
|
identifier = geom.getName();
|
||||||
} else {
|
} else {
|
||||||
static int unnamedGeomCtr = 0;
|
static int unnamedCtr = 0;
|
||||||
geomName = formatString("unnamedGeom_%i", unnamedGeomCtr);
|
identifier = formatString("unnamedGeom_%i", unnamedCtr++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SLog(EInfo, "Converting geometry \"%s\" (instantiated by %s)..", geomName.c_str(), nodeName.c_str());
|
|
||||||
|
SLog(EInfo, "Converting geometry \"%s\" (instantiated by %s)..", identifier.c_str(), prefixName.c_str());
|
||||||
|
|
||||||
domMesh *mesh = geom.getMesh().cast();
|
domMesh *mesh = geom.getMesh().cast();
|
||||||
if (!mesh)
|
if (!mesh)
|
||||||
|
@ -293,7 +297,7 @@ void loadGeometry(std::string nodeName, Transform transform, std::ostream &os, d
|
||||||
|
|
||||||
const domInputLocal_Array &vertInputs = mesh->getVertices()->getInput_array();
|
const domInputLocal_Array &vertInputs = mesh->getVertices()->getInput_array();
|
||||||
|
|
||||||
std::string xmlName = nodeName + std::string("_") + geom.getId();
|
std::string xmlName = prefixName + identifier;
|
||||||
int geomIndex = 0;
|
int geomIndex = 0;
|
||||||
|
|
||||||
domTriangles_Array &trianglesArray = mesh->getTriangles_array();
|
domTriangles_Array &trianglesArray = mesh->getTriangles_array();
|
||||||
|
@ -366,7 +370,7 @@ void loadGeometry(std::string nodeName, Transform transform, std::ostream &os, d
|
||||||
tess_nSources = data->nSources;
|
tess_nSources = data->nSources;
|
||||||
|
|
||||||
for (size_t j=0; j<vcount.getCount(); ++j) {
|
for (size_t j=0; j<vcount.getCount(); ++j) {
|
||||||
size_t vertexCount = vcount.get(j);
|
size_t vertexCount = (size_t) vcount.get(j);
|
||||||
|
|
||||||
domUint *temp = new domUint[vertexCount * data->nSources];
|
domUint *temp = new domUint[vertexCount * data->nSources];
|
||||||
for (size_t l = 0; l<vertexCount * data->nSources; ++l)
|
for (size_t l = 0; l<vertexCount * data->nSources; ++l)
|
||||||
|
@ -433,7 +437,17 @@ void loadMaterialParam(GeometryConverter *cvt, std::ostream &os, const std::stri
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, StringMap &_idToTexture) {
|
void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, StringMap &_idToTexture) {
|
||||||
SLog(EInfo, "Converting material \"%s\" ..", mat.getName());
|
std::string identifier;
|
||||||
|
if (mat.getId() != NULL) {
|
||||||
|
identifier = mat.getId();
|
||||||
|
} else {
|
||||||
|
if (mat.getName() != NULL) {
|
||||||
|
identifier = mat.getName();
|
||||||
|
} else {
|
||||||
|
static int unnamedCtr = 0;
|
||||||
|
identifier = formatString("unnamedMat_%i", unnamedCtr++);
|
||||||
|
}
|
||||||
|
}
|
||||||
StringMap idToTexture = _idToTexture;
|
StringMap idToTexture = _idToTexture;
|
||||||
|
|
||||||
daeURI &effRef = mat.getInstance_effect()->getUrl();
|
daeURI &effRef = mat.getInstance_effect()->getUrl();
|
||||||
|
@ -483,7 +497,9 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
||||||
SLog(EError, "The technique element is missing!");
|
SLog(EError, "The technique element is missing!");
|
||||||
|
|
||||||
domProfile_COMMON::domTechnique::domPhong* phong = technique->getPhong();
|
domProfile_COMMON::domTechnique::domPhong* phong = technique->getPhong();
|
||||||
|
domProfile_COMMON::domTechnique::domBlinn* blinn = technique->getBlinn();
|
||||||
domProfile_COMMON::domTechnique::domLambert* lambert = technique->getLambert();
|
domProfile_COMMON::domTechnique::domLambert* lambert = technique->getLambert();
|
||||||
|
domProfile_COMMON::domTechnique::domConstant* constant = technique->getConstant();
|
||||||
|
|
||||||
if (phong) {
|
if (phong) {
|
||||||
domCommon_color_or_texture_type* diffuse = phong->getDiffuse();
|
domCommon_color_or_texture_type* diffuse = phong->getDiffuse();
|
||||||
|
@ -499,12 +515,12 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
||||||
isDiffuse = true;
|
isDiffuse = true;
|
||||||
}
|
}
|
||||||
if (isDiffuse) {
|
if (isDiffuse) {
|
||||||
os << "\t<bsdf id=\"" << mat.getId() << "\" type=\"lambertian\">" << endl;
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"lambertian\">" << endl;
|
||||||
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, false);
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, false);
|
||||||
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, true);
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, true);
|
||||||
os << "\t</bsdf>" << endl << endl;
|
os << "\t</bsdf>" << endl << endl;
|
||||||
} else {
|
} else {
|
||||||
os << "\t<bsdf id=\"" << mat.getId() << "\" type=\"phong\">" << endl;
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"phong\">" << endl;
|
||||||
os << "\t\t<float name=\"specularReflectance\" value=\"1\"/>" << endl;
|
os << "\t\t<float name=\"specularReflectance\" value=\"1\"/>" << endl;
|
||||||
os << "\t\t<float name=\"diffuseReflectance\" value=\"1\"/>" << endl;
|
os << "\t\t<float name=\"diffuseReflectance\" value=\"1\"/>" << endl;
|
||||||
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, false);
|
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, false);
|
||||||
|
@ -517,17 +533,65 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
||||||
}
|
}
|
||||||
} else if (lambert) {
|
} else if (lambert) {
|
||||||
domCommon_color_or_texture_type* diffuse = lambert->getDiffuse();
|
domCommon_color_or_texture_type* diffuse = lambert->getDiffuse();
|
||||||
os << "\t<bsdf id=\"" << mat.getId() << "\" type=\"lambertian\">" << endl;
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"lambertian\">" << endl;
|
||||||
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, false);
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, false);
|
||||||
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, true);
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, true);
|
||||||
os << "\t</bsdf>" << endl << endl;
|
os << "\t</bsdf>" << endl << endl;
|
||||||
|
} else if (blinn) {
|
||||||
|
SLog(EWarn, "\"%s\": Encountered a \"blinn\" COLLADA material, which is currently "
|
||||||
|
"unsupported in Mitsuba -- replacing it using a Phong material.", identifier.c_str());
|
||||||
|
domCommon_color_or_texture_type* diffuse = blinn->getDiffuse();
|
||||||
|
domCommon_color_or_texture_type* specular = blinn->getSpecular();
|
||||||
|
domCommon_float_or_param_type* shininess = blinn->getShininess();
|
||||||
|
bool isDiffuse = false;
|
||||||
|
|
||||||
|
if (specular->getColor().cast()) {
|
||||||
|
domFloat4 &colValue = specular->getColor()->getValue();
|
||||||
|
if (colValue.get(0) == colValue.get(1) &&
|
||||||
|
colValue.get(1) == colValue.get(2) &&
|
||||||
|
colValue.get(2) == 0)
|
||||||
|
isDiffuse = true;
|
||||||
|
}
|
||||||
|
if (isDiffuse) {
|
||||||
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"lambertian\">" << endl;
|
||||||
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, false);
|
||||||
|
loadMaterialParam(cvt, os, "reflectance", idToTexture, diffuse, true);
|
||||||
|
os << "\t</bsdf>" << endl << endl;
|
||||||
|
} else {
|
||||||
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"blinn\">" << endl;
|
||||||
|
os << "\t\t<float name=\"specularReflectance\" value=\"1\"/>" << endl;
|
||||||
|
os << "\t\t<float name=\"diffuseReflectance\" value=\"1\"/>" << endl;
|
||||||
|
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, false);
|
||||||
|
loadMaterialParam(cvt, os, "specularColor", idToTexture, specular, false);
|
||||||
|
loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, false);
|
||||||
|
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, true);
|
||||||
|
loadMaterialParam(cvt, os, "specularColor", idToTexture, specular, true);
|
||||||
|
loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, true);
|
||||||
|
os << "\t</bsdf>" << endl << endl;
|
||||||
|
}
|
||||||
|
} else if (constant) {
|
||||||
|
SLog(EWarn, "\"%s\": Encountered a \"constant\" COLLADA material, which is currently "
|
||||||
|
"unsupported in Mitsuba -- replacing it using a Lambertian material.", identifier.c_str());
|
||||||
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"lambertian\"/>" << endl << endl;
|
||||||
} else {
|
} else {
|
||||||
SLog(EError, "Material type not supported! (must be Lambertian/Phong)");
|
SLog(EError, "Material type not supported! (must be Lambertian/Phong/Blinn/Constant)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
SLog(EInfo, "Converting light \"%s\" ..", light.getName());
|
std::string identifier;
|
||||||
|
if (light.getId() != NULL) {
|
||||||
|
identifier = light.getId();
|
||||||
|
} else {
|
||||||
|
if (light.getName() != NULL) {
|
||||||
|
identifier = light.getName();
|
||||||
|
} else {
|
||||||
|
static int unnamedCtr = 0;
|
||||||
|
identifier = formatString("unnamedLight_%i", unnamedCtr++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SLog(EInfo, "Converting light \"%s\" ..", identifier.c_str());
|
||||||
char *end_ptr = NULL;
|
char *end_ptr = NULL;
|
||||||
|
|
||||||
// Lights in Mitsuba point along the positive Z axis (COLLADA: neg. Z)
|
// Lights in Mitsuba point along the positive Z axis (COLLADA: neg. Z)
|
||||||
|
@ -560,9 +624,9 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
if (point->getQuadratic_attenuation() && point->getQuadratic_attenuation()->getValue() != 1)
|
if (point->getQuadratic_attenuation() && point->getQuadratic_attenuation()->getValue() != 1)
|
||||||
notQuadratic = true;
|
notQuadratic = true;
|
||||||
if (notQuadratic)
|
if (notQuadratic)
|
||||||
SLog(EWarn, "Point light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", light.getId());
|
SLog(EWarn, "Point light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", identifier.c_str());
|
||||||
domFloat3 &color = point->getColor()->getValue();
|
domFloat3 &color = point->getColor()->getValue();
|
||||||
os << "\t<luminaire id=\"" << light.getId() << "\" type=\"point\">" << endl;
|
os << "\t<luminaire id=\"" << identifier << "\" type=\"point\">" << endl;
|
||||||
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl << endl;
|
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl << endl;
|
||||||
os << "\t\t<transform name=\"toWorld\">" << endl;
|
os << "\t\t<transform name=\"toWorld\">" << endl;
|
||||||
os << "\t\t\t<translate x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\"/>" << endl;
|
os << "\t\t\t<translate x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\"/>" << endl;
|
||||||
|
@ -573,7 +637,7 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
domLight::domTechnique_common::domDirectional *directional = light.getTechnique_common()->getDirectional().cast();
|
domLight::domTechnique_common::domDirectional *directional = light.getTechnique_common()->getDirectional().cast();
|
||||||
if (directional) {
|
if (directional) {
|
||||||
domFloat3 &color = directional->getColor()->getValue();
|
domFloat3 &color = directional->getColor()->getValue();
|
||||||
os << "\t<luminaire id=\"" << light.getId() << "\" type=\"directional\">" << endl;
|
os << "\t<luminaire id=\"" << identifier << "\" type=\"directional\">" << endl;
|
||||||
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl << endl;
|
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl << endl;
|
||||||
os << "\t\t<transform name=\"toWorld\">" << endl;
|
os << "\t\t<transform name=\"toWorld\">" << endl;
|
||||||
os << "\t\t\t<lookAt ox=\"" << pos.x << "\" oy=\"" << pos.y << "\" oz=\"" << pos.z << "\" tx=\"" << target.x << "\" ty=\"" << target.y << "\" tz=\"" << target.z << "\"/>" << endl;
|
os << "\t\t\t<lookAt ox=\"" << pos.x << "\" oy=\"" << pos.y << "\" oz=\"" << pos.z << "\" tx=\"" << target.x << "\" ty=\"" << target.y << "\" tz=\"" << target.z << "\"/>" << endl;
|
||||||
|
@ -591,12 +655,12 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
if (spot->getQuadratic_attenuation() && spot->getQuadratic_attenuation()->getValue() != 1)
|
if (spot->getQuadratic_attenuation() && spot->getQuadratic_attenuation()->getValue() != 1)
|
||||||
notQuadratic = true;
|
notQuadratic = true;
|
||||||
if (notQuadratic)
|
if (notQuadratic)
|
||||||
SLog(EWarn, "Spot light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", light.getId());
|
SLog(EWarn, "Spot light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", identifier.c_str());
|
||||||
domFloat3 &color = spot->getColor()->getValue();
|
domFloat3 &color = spot->getColor()->getValue();
|
||||||
Float falloffAngle = 180.0f;
|
Float falloffAngle = 180.0f;
|
||||||
if (spot->getFalloff_angle())
|
if (spot->getFalloff_angle())
|
||||||
falloffAngle = (Float) spot->getFalloff_angle()->getValue();
|
falloffAngle = (Float) spot->getFalloff_angle()->getValue();
|
||||||
os << "\t<luminaire id=\"" << light.getId() << "\" type=\"spot\">" << endl;
|
os << "\t<luminaire id=\"" << identifier << "\" type=\"spot\">" << endl;
|
||||||
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl;
|
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl;
|
||||||
os << "\t\t<float name=\"cutoffAngle\" value=\"" << falloffAngle/2 << "\"/>" << endl << endl;
|
os << "\t\t<float name=\"cutoffAngle\" value=\"" << falloffAngle/2 << "\"/>" << endl << endl;
|
||||||
os << "\t\t<transform name=\"toWorld\">" << endl;
|
os << "\t\t<transform name=\"toWorld\">" << endl;
|
||||||
|
@ -607,7 +671,7 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
domLight::domTechnique_common::domAmbient *ambient = light.getTechnique_common()->getAmbient().cast();
|
domLight::domTechnique_common::domAmbient *ambient = light.getTechnique_common()->getAmbient().cast();
|
||||||
if (ambient) {
|
if (ambient) {
|
||||||
domFloat3 &color = ambient->getColor()->getValue();
|
domFloat3 &color = ambient->getColor()->getValue();
|
||||||
os << "\t<luminaire id=\"" << light.getId() << "\" type=\"constant\">" << endl;
|
os << "\t<luminaire id=\"" << identifier << "\" type=\"constant\">" << endl;
|
||||||
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl;
|
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl;
|
||||||
os << "\t</luminaire>" << endl << endl;
|
os << "\t</luminaire>" << endl << endl;
|
||||||
}
|
}
|
||||||
|
@ -617,16 +681,28 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
||||||
|
|
||||||
void loadImage(GeometryConverter *cvt, std::ostream &os, const std::string &textureDir,
|
void loadImage(GeometryConverter *cvt, std::ostream &os, const std::string &textureDir,
|
||||||
domImage &image, StringMap &idToTexture, StringMap &fileToId) {
|
domImage &image, StringMap &idToTexture, StringMap &fileToId) {
|
||||||
SLog(EInfo, "Converting texture \"%s\" ..", image.getName());
|
std::string identifier;
|
||||||
|
if (image.getId() != NULL) {
|
||||||
|
identifier = image.getId();
|
||||||
|
} else {
|
||||||
|
if (image.getName() != NULL) {
|
||||||
|
identifier = image.getName();
|
||||||
|
} else {
|
||||||
|
static int unnamedCtr = 0;
|
||||||
|
identifier = formatString("unnamedTexture_%i", unnamedCtr++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SLog(EInfo, "Converting texture \"%s\" ..", identifier.c_str());
|
||||||
|
|
||||||
std::string filename = cdom::uriToFilePath(image.getInit_from()->getValue().str());
|
std::string filename = cdom::uriToFilePath(image.getInit_from()->getValue().str());
|
||||||
if (fileToId.find(filename) != fileToId.end()) {
|
if (fileToId.find(filename) != fileToId.end()) {
|
||||||
idToTexture[image.getId()] = fileToId[filename];
|
idToTexture[identifier] = fileToId[filename];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
idToTexture[image.getId()] = image.getId();
|
idToTexture[identifier] = identifier;
|
||||||
fileToId[filename] = image.getId();
|
fileToId[filename] = identifier;
|
||||||
|
|
||||||
boost::filesystem::path path = boost::filesystem::path(filename, boost::filesystem::native);
|
boost::filesystem::path path = boost::filesystem::path(filename, boost::filesystem::native);
|
||||||
std::string targetPath = textureDir + path.leaf();
|
std::string targetPath = textureDir + path.leaf();
|
||||||
|
@ -655,13 +731,25 @@ void loadImage(GeometryConverter *cvt, std::ostream &os, const std::string &text
|
||||||
output->close();
|
output->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "\t<texture id=\"" << image.getId() << "\" type=\"ldrtexture\">" << endl;
|
os << "\t<texture id=\"" << identifier << "\" type=\"ldrtexture\">" << endl;
|
||||||
os << "\t\t<string name=\"filename\" value=\"" << textureDir + path.leaf() << "\"/>" << endl;
|
os << "\t\t<string name=\"filename\" value=\"" << textureDir + path.leaf() << "\"/>" << endl;
|
||||||
os << "\t</texture>" << endl << endl;
|
os << "\t</texture>" << endl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, domCamera &camera) {
|
void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, domCamera &camera) {
|
||||||
SLog(EInfo, "Converting camera \"%s\" ..", camera.getName());
|
std::string identifier;
|
||||||
|
if (camera.getId() != NULL) {
|
||||||
|
identifier = camera.getId();
|
||||||
|
} else {
|
||||||
|
if (camera.getName() != NULL) {
|
||||||
|
identifier = camera.getName();
|
||||||
|
} else {
|
||||||
|
static int unnamedCtr = 0;
|
||||||
|
identifier = formatString("unnamedCamera_%i", unnamedCtr++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SLog(EInfo, "Converting camera \"%s\" ..", identifier.c_str());
|
||||||
Float aspect = 1.0f;
|
Float aspect = 1.0f;
|
||||||
int xres=768;
|
int xres=768;
|
||||||
|
|
||||||
|
@ -683,7 +771,7 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
||||||
xres = cvt->m_xres;
|
xres = cvt->m_xres;
|
||||||
aspect = (Float) cvt->m_xres / (Float) cvt->m_yres;
|
aspect = (Float) cvt->m_xres / (Float) cvt->m_yres;
|
||||||
}
|
}
|
||||||
os << "\t<camera id=\"" << camera.getId() << "\" type=\"orthographic\">" << endl;
|
os << "\t<camera id=\"" << identifier << "\" type=\"orthographic\">" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
domCamera::domOptics::domTechnique_common::domPerspective* persp = camera.getOptics()->
|
domCamera::domOptics::domTechnique_common::domPerspective* persp = camera.getOptics()->
|
||||||
|
@ -702,9 +790,9 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
os << "\t<camera id=\"" << camera.getId() << "\" type=\"perspective\">" << endl;
|
os << "\t<camera id=\"" << identifier << "\" type=\"perspective\">" << endl;
|
||||||
if (persp->getXfov().cast()) {
|
if (persp->getXfov().cast()) {
|
||||||
Float xFov = persp->getXfov()->getValue();
|
Float xFov = (Float) persp->getXfov()->getValue();
|
||||||
if (std::abs(xFov-1.0f) < Epsilon && cvt->m_fov == -1) {
|
if (std::abs(xFov-1.0f) < Epsilon && cvt->m_fov == -1) {
|
||||||
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
|
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
|
||||||
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
|
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
|
||||||
|
@ -718,7 +806,7 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
||||||
else
|
else
|
||||||
os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
|
os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
|
||||||
} else if (persp->getYfov().cast()) {
|
} else if (persp->getYfov().cast()) {
|
||||||
Float yFov = persp->getYfov()->getValue();
|
Float yFov = (Float) persp->getYfov()->getValue();
|
||||||
if (std::abs(yFov-1.0) < Epsilon && cvt->m_fov == -1) {
|
if (std::abs(yFov-1.0) < Epsilon && cvt->m_fov == -1) {
|
||||||
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
|
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
|
||||||
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
|
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
|
||||||
|
@ -753,19 +841,19 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
||||||
domNode &node, const std::string &meshesDir) {
|
domNode &node, std::string prefixName, const std::string &meshesDir) {
|
||||||
std::string nodeName;
|
std::string identifier;
|
||||||
if (node.getName() != NULL) {
|
if (node.getId() != NULL) {
|
||||||
nodeName = node.getName();
|
identifier = node.getId();
|
||||||
} else {
|
} else {
|
||||||
if (node.getId() != NULL) {
|
if (node.getName() != NULL) {
|
||||||
nodeName = node.getId();
|
identifier = node.getName();
|
||||||
} else {
|
} else {
|
||||||
static int unnamedNodeCtr = 0;
|
static int unnamedCtr = 0;
|
||||||
nodeName = formatString("unnamedNode_%i", unnamedNodeCtr);
|
identifier = formatString("unnamedNode_%i", unnamedCtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SLog(EInfo, "Converting node \"%s\" ..", nodeName.c_str());
|
SLog(EInfo, "Converting node \"%s\" ..", identifier.c_str());
|
||||||
|
|
||||||
daeTArray<daeSmartRef<daeElement> > children = node.getChildren();
|
daeTArray<daeSmartRef<daeElement> > children = node.getChildren();
|
||||||
/* Parse transformations */
|
/* Parse transformations */
|
||||||
|
@ -824,7 +912,7 @@ void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
||||||
|
|
||||||
if (!geom)
|
if (!geom)
|
||||||
SLog(EError, "Could not find a referenced geometry object!");
|
SLog(EError, "Could not find a referenced geometry object!");
|
||||||
loadGeometry(nodeName, transform, os, *geom, matLookupTable, meshesDir);
|
loadGeometry(prefixName, transform, os, *geom, matLookupTable, meshesDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate over all light references */
|
/* Iterate over all light references */
|
||||||
|
@ -850,7 +938,7 @@ void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
||||||
/* Recursively iterate through sub-nodes */
|
/* Recursively iterate through sub-nodes */
|
||||||
domNode_Array &nodes = node.getNode_array();
|
domNode_Array &nodes = node.getNode_array();
|
||||||
for (size_t i=0; i<nodes.getCount(); ++i)
|
for (size_t i=0; i<nodes.getCount(); ++i)
|
||||||
loadNode(cvt, transform, os, *nodes[i], meshesDir);
|
loadNode(cvt, transform, os, *nodes[i], prefixName + identifier + "_" , meshesDir);
|
||||||
|
|
||||||
/* Recursively iterate through <instance_node> elements */
|
/* Recursively iterate through <instance_node> elements */
|
||||||
domInstance_node_Array &instanceNodes = node.getInstance_node_array();
|
domInstance_node_Array &instanceNodes = node.getInstance_node_array();
|
||||||
|
@ -858,7 +946,7 @@ void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
||||||
domNode *node = daeSafeCast<domNode>(instanceNodes[i]->getUrl().getElement());
|
domNode *node = daeSafeCast<domNode>(instanceNodes[i]->getUrl().getElement());
|
||||||
if (!node)
|
if (!node)
|
||||||
SLog(EError, "Could not find a referenced node!");
|
SLog(EError, "Could not find a referenced node!");
|
||||||
loadNode(cvt, transform, os, *node, meshesDir);
|
loadNode(cvt, transform, os, *node, prefixName + identifier + "_", meshesDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +1037,7 @@ void GeometryConverter::convertCollada(const std::string &inputFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i=0; i<nodes.getCount(); ++i)
|
for (size_t i=0; i<nodes.getCount(); ++i)
|
||||||
loadNode(this, Transform(), os, *nodes[i], meshesDirectory);
|
loadNode(this, Transform(), os, *nodes[i], "", meshesDirectory);
|
||||||
|
|
||||||
os << "</scene>" << endl;
|
os << "</scene>" << endl;
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,15 @@ int colladaMain(int argc, char **argv) {
|
||||||
converter.setMapSmallerSide(mapSmallerSide);
|
converter.setMapSmallerSide(mapSmallerSide);
|
||||||
converter.setSamplesPerPixel(samplesPerPixel);
|
converter.setSamplesPerPixel(samplesPerPixel);
|
||||||
converter.setFov(fov);
|
converter.setFov(fov);
|
||||||
|
|
||||||
|
const Logger *logger = Thread::getThread()->getLogger();
|
||||||
|
size_t initialWarningCount = logger->getWarningCount();
|
||||||
converter.convert(argv[optind], "", argv[optind+1], argc > optind+2 ? argv[optind+2] : "");
|
converter.convert(argv[optind], "", argv[optind+1], argc > optind+2 ? argv[optind+2] : "");
|
||||||
|
size_t warningCount = logger->getWarningCount() - initialWarningCount;
|
||||||
|
|
||||||
|
if (warningCount > 0)
|
||||||
|
SLog(EInfo, "Encountered " SIZE_T_FMT " warnings -- please check the "
|
||||||
|
"messages above for details.", warningCount);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,19 +146,21 @@ Bitmap::Bitmap(int width, int height, int bpp)
|
||||||
m_gamma = -1.0f; // sRGB
|
m_gamma = -1.0f; // sRGB
|
||||||
|
|
||||||
// 1-bit masks are stored in a packed format.
|
// 1-bit masks are stored in a packed format.
|
||||||
m_size = (size_t) std::ceil((m_width * m_height * m_bpp) / 8.0f);
|
m_size = (size_t) std::ceil((m_width * m_height * m_bpp) / 8.0);
|
||||||
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap::Bitmap(EFileFormat format, Stream *stream) : m_data(NULL) {
|
Bitmap::Bitmap(EFileFormat format, Stream *stream) : m_data(NULL) {
|
||||||
if (format == EPNG)
|
if (format == EPNG)
|
||||||
loadPNG(stream);
|
loadPNG(stream);
|
||||||
else if (format == ETGA)
|
|
||||||
loadTGA(stream);
|
|
||||||
else if (format == EJPEG)
|
else if (format == EJPEG)
|
||||||
loadJPEG(stream);
|
loadJPEG(stream);
|
||||||
else if (format == EEXR)
|
else if (format == EEXR)
|
||||||
loadEXR(stream);
|
loadEXR(stream);
|
||||||
|
else if (format == ETGA)
|
||||||
|
loadTGA(stream);
|
||||||
|
else if (format == EBMP)
|
||||||
|
loadBMP(stream);
|
||||||
else
|
else
|
||||||
Log(EError, "Bitmap: Invalid file format!");
|
Log(EError, "Bitmap: Invalid file format!");
|
||||||
}
|
}
|
||||||
|
@ -226,6 +228,73 @@ void Bitmap::loadTGA(Stream *stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::loadBMP(Stream *stream) {
|
||||||
|
#if defined(WIN32)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#endif
|
||||||
|
struct {
|
||||||
|
uint16_t magic;
|
||||||
|
uint32_t size;
|
||||||
|
uint16_t creator1, creator2;
|
||||||
|
uint32_t offset;
|
||||||
|
} BMPFileHeader
|
||||||
|
#if !defined(WIN32)
|
||||||
|
__attribute__((__packed__))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t header_sz;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint16_t nplanes;
|
||||||
|
uint16_t bitspp;
|
||||||
|
uint32_t compress_type;
|
||||||
|
uint32_t bmp_bytesz;
|
||||||
|
uint32_t hres;
|
||||||
|
uint32_t vres;
|
||||||
|
uint32_t ncolors;
|
||||||
|
uint32_t nimpcolors;
|
||||||
|
} DIBHeader
|
||||||
|
#if defined(WIN32)
|
||||||
|
;
|
||||||
|
#pragma pack(pop)
|
||||||
|
#else
|
||||||
|
__attribute__((__packed__));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Assert(sizeof(BMPFileHeader) == 14);
|
||||||
|
Assert(sizeof(DIBHeader) == 40);
|
||||||
|
|
||||||
|
stream->read(&BMPFileHeader, sizeof(BMPFileHeader));
|
||||||
|
|
||||||
|
if (memcmp(&BMPFileHeader.magic, "BM", 2) != 0)
|
||||||
|
Log(EError, "Unsupported BMP format encountered (invalid file header)!");
|
||||||
|
|
||||||
|
stream->read(&DIBHeader, sizeof(DIBHeader));
|
||||||
|
|
||||||
|
if (DIBHeader.header_sz != 40 || DIBHeader.nplanes != 1)
|
||||||
|
Log(EError, "Unsupported BMP format encountered (strange DIB header)!");
|
||||||
|
|
||||||
|
if (DIBHeader.ncolors != 0)
|
||||||
|
Log(EError, "Only BMP images without a palette are supported for now");
|
||||||
|
|
||||||
|
if (DIBHeader.bitspp != 8 && DIBHeader.bitspp != 24)
|
||||||
|
Log(EError, "Only 8- and 24-bit BMP images are supported for now");
|
||||||
|
|
||||||
|
m_width = DIBHeader.width;
|
||||||
|
m_height = DIBHeader.height;
|
||||||
|
m_bpp = DIBHeader.bitspp;
|
||||||
|
|
||||||
|
m_size = m_width * m_height * (m_bpp / 8);
|
||||||
|
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
||||||
|
|
||||||
|
Log(ETrace, "Reading %ix%ix%i PNG file", m_width, m_height, m_bpp);
|
||||||
|
|
||||||
|
if (DIBHeader.compress_type != 0)
|
||||||
|
Log(EError, "Only uncompressed BMP images are supported for now");
|
||||||
|
}
|
||||||
|
|
||||||
void Bitmap::loadPNG(Stream *stream) {
|
void Bitmap::loadPNG(Stream *stream) {
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
|
@ -309,7 +378,7 @@ void Bitmap::loadPNG(Stream *stream) {
|
||||||
&colortype, &interlacetype, &compressiontype, &filtertype);
|
&colortype, &interlacetype, &compressiontype, &filtertype);
|
||||||
m_width = width; m_height = height;
|
m_width = width; m_height = height;
|
||||||
|
|
||||||
m_size = (size_t) std::ceil((m_width * m_height * m_bpp) / 8.0f);
|
m_size = (size_t) std::ceil((m_width * m_height * m_bpp) / 8.0);
|
||||||
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
||||||
|
|
||||||
rows = new png_bytep[m_height];
|
rows = new png_bytep[m_height];
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
Logger::Logger(ELogLevel level)
|
Logger::Logger(ELogLevel level)
|
||||||
: m_logLevel(level) {
|
: m_logLevel(level), m_warningCount(0) {
|
||||||
m_mutex = new Mutex();
|
m_mutex = new Mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@ void Logger::log(ELogLevel level, const Class *theClass,
|
||||||
|
|
||||||
if (level < EError) {
|
if (level < EError) {
|
||||||
m_mutex->lock();
|
m_mutex->lock();
|
||||||
|
if (level >= EWarn)
|
||||||
|
m_warningCount++;
|
||||||
for (unsigned int i=0; i<m_appenders.size(); ++i)
|
for (unsigned int i=0; i<m_appenders.size(); ++i)
|
||||||
m_appenders[i]->append(level, text);
|
m_appenders[i]->append(level, text);
|
||||||
m_mutex->unlock();
|
m_mutex->unlock();
|
||||||
|
|
|
@ -142,6 +142,8 @@ Float TriMesh::sampleArea(ShapeSamplingRecord &sRec, const Point2 &sample) const
|
||||||
|
|
||||||
void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, bool complain) {
|
void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, bool complain) {
|
||||||
/* Calculate smooth normals if there aren't any */
|
/* Calculate smooth normals if there aren't any */
|
||||||
|
int zeroArea = 0, zeroNormals = 0;
|
||||||
|
|
||||||
if (!hasNormals) {
|
if (!hasNormals) {
|
||||||
for (unsigned int i=0; i<m_vertexCount; i++)
|
for (unsigned int i=0; i<m_vertexCount; i++)
|
||||||
m_vertexBuffer[i].n = Normal(0.0, 0.0f, 0.0f);
|
m_vertexBuffer[i].n = Normal(0.0, 0.0f, 0.0f);
|
||||||
|
@ -153,8 +155,8 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
Float length = n.length();
|
Float length = n.length();
|
||||||
if (length != 0)
|
if (length != 0)
|
||||||
n /= length;
|
n /= length;
|
||||||
else if (complain)
|
else
|
||||||
Log(EWarn, "Invalid geometry - cannot calculate normals");
|
zeroArea++;
|
||||||
m_vertexBuffer[m_triangles[i].idx[0]].n += n;
|
m_vertexBuffer[m_triangles[i].idx[0]].n += n;
|
||||||
m_vertexBuffer[m_triangles[i].idx[1]].n += n;
|
m_vertexBuffer[m_triangles[i].idx[1]].n += n;
|
||||||
m_vertexBuffer[m_triangles[i].idx[2]].n += n;
|
m_vertexBuffer[m_triangles[i].idx[2]].n += n;
|
||||||
|
@ -182,8 +184,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
for isotropic BxDFs) */
|
for isotropic BxDFs) */
|
||||||
for (unsigned int i=0; i<m_vertexCount; i++) {
|
for (unsigned int i=0; i<m_vertexCount; i++) {
|
||||||
if (m_vertexBuffer[i].n.isZero()) {
|
if (m_vertexBuffer[i].n.isZero()) {
|
||||||
if (complain)
|
zeroNormals++;
|
||||||
Log(EWarn, "Mesh has zero normals!");
|
|
||||||
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
||||||
}
|
}
|
||||||
coordinateSystem(m_vertexBuffer[i].n, m_vertexBuffer[i].dpdu, m_vertexBuffer[i].dpdv);
|
coordinateSystem(m_vertexBuffer[i].n, m_vertexBuffer[i].dpdu, m_vertexBuffer[i].dpdv);
|
||||||
|
@ -196,8 +197,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
m_vertexBuffer[i].dpdu = Vector(0.0, 0.0f, 0.0f);
|
m_vertexBuffer[i].dpdu = Vector(0.0, 0.0f, 0.0f);
|
||||||
m_vertexBuffer[i].dpdv = Vector(0.0, 0.0f, 0.0f);
|
m_vertexBuffer[i].dpdv = Vector(0.0, 0.0f, 0.0f);
|
||||||
if (m_vertexBuffer[i].n.isZero()) {
|
if (m_vertexBuffer[i].n.isZero()) {
|
||||||
if (complain)
|
zeroNormals++;
|
||||||
Log(EWarn, "Mesh has zero normals!");
|
|
||||||
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
||||||
}
|
}
|
||||||
sharers[i] = 0;
|
sharers[i] = 0;
|
||||||
|
@ -230,8 +230,8 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
Float length = n.length();
|
Float length = n.length();
|
||||||
if (length != 0)
|
if (length != 0)
|
||||||
n /= length;
|
n /= length;
|
||||||
else if (complain)
|
else
|
||||||
Log(EWarn, "Mesh contains invalid geometry!");
|
zeroArea++;
|
||||||
dpdu = cross(n, dpdv);
|
dpdu = cross(n, dpdv);
|
||||||
|
|
||||||
if (dpdu.length() == 0.0f) {
|
if (dpdu.length() == 0.0f) {
|
||||||
|
@ -246,8 +246,8 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
Float length = n.length();
|
Float length = n.length();
|
||||||
if (length != 0)
|
if (length != 0)
|
||||||
n /= length;
|
n /= length;
|
||||||
else if (complain)
|
else
|
||||||
Log(EWarn, "Mesh contains invalid geometry!");
|
zeroArea++;
|
||||||
dpdv = cross(dpdu, n);
|
dpdv = cross(dpdu, n);
|
||||||
|
|
||||||
if (dpdv.length() == 0.0f) {
|
if (dpdv.length() == 0.0f) {
|
||||||
|
@ -265,6 +265,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
m_vertexBuffer[idx2].dpdv += dpdv;
|
m_vertexBuffer[idx2].dpdv += dpdv;
|
||||||
sharers[idx0]++; sharers[idx1]++; sharers[idx2]++;
|
sharers[idx0]++; sharers[idx1]++; sharers[idx2]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Orthogonalization + Normalization pass */
|
/* Orthogonalization + Normalization pass */
|
||||||
for (unsigned int i=0; i<m_vertexCount; i++) {
|
for (unsigned int i=0; i<m_vertexCount; i++) {
|
||||||
Vector dpdu = m_vertexBuffer[i].dpdu;
|
Vector dpdu = m_vertexBuffer[i].dpdu;
|
||||||
|
@ -286,6 +287,10 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
||||||
}
|
}
|
||||||
delete[] sharers;
|
delete[] sharers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (complain && (zeroArea > 0 || zeroNormals > 0))
|
||||||
|
Log(EWarn, "Mesh contains invalid geometry: %i zero area triangles "
|
||||||
|
"and %i zero normals found!", zeroArea, zeroNormals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriMesh::serialize(Stream *stream, InstanceManager *manager) const {
|
void TriMesh::serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
|
|
|
@ -112,6 +112,9 @@ void ImportDialog::accept() {
|
||||||
if (!m_resolver->contains(filePath))
|
if (!m_resolver->contains(filePath))
|
||||||
m_resolver->addPath(filePath);
|
m_resolver->addPath(filePath);
|
||||||
|
|
||||||
|
const Logger *logger = Thread::getThread()->getLogger();
|
||||||
|
size_t initialWarningCount = logger->getWarningCount();
|
||||||
|
|
||||||
ref<SceneImporter> importingThread = new SceneImporter(this,
|
ref<SceneImporter> importingThread = new SceneImporter(this,
|
||||||
m_resolver, sourceFile.toStdString(), directory.toStdString(),
|
m_resolver, sourceFile.toStdString(), directory.toStdString(),
|
||||||
targetScene.toStdString(), adjustmentFile.toStdString(),
|
targetScene.toStdString(), adjustmentFile.toStdString(),
|
||||||
|
@ -122,15 +125,22 @@ void ImportDialog::accept() {
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
importingThread->wait(20);
|
importingThread->wait(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
importingThread->join();
|
importingThread->join();
|
||||||
|
|
||||||
dialog->hide();
|
dialog->hide();
|
||||||
delete dialog;
|
delete dialog;
|
||||||
|
|
||||||
if (importingThread->getResult().length() > 0)
|
if (importingThread->getResult().length() > 0) {
|
||||||
|
size_t warningCount = logger->getWarningCount() - initialWarningCount;
|
||||||
|
if (warningCount > 0)
|
||||||
|
QMessageBox::warning(this, tr("Scene Import"),
|
||||||
|
tr("Encountered %1 warnings while importing -- please see "
|
||||||
|
"the log for details.").arg(warningCount), QMessageBox::Ok);
|
||||||
((MainWindow *) parent())->loadFile(QString(importingThread->getResult().c_str()));
|
((MainWindow *) parent())->loadFile(QString(importingThread->getResult().c_str()));
|
||||||
else
|
} else {
|
||||||
QMessageBox::critical(this, tr("Scene Import"),
|
QMessageBox::critical(this, tr("Scene Import"),
|
||||||
tr("Conversion failed -- please see the log for details."),
|
tr("Conversion failed -- please see the log for details."),
|
||||||
QMessageBox::Ok);
|
QMessageBox::Ok);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gamma-corrected bitmap texture using the JPG, TGA or PNG file format
|
* Gamma-corrected bitmap texture using the JPG, PNG, TGA or BMP
|
||||||
*/
|
*/
|
||||||
class LDRTexture : public Texture {
|
class LDRTexture : public Texture {
|
||||||
public:
|
public:
|
||||||
|
@ -30,6 +30,8 @@ public:
|
||||||
m_format = Bitmap::EPNG;
|
m_format = Bitmap::EPNG;
|
||||||
else if (endsWith(lower, ".tga"))
|
else if (endsWith(lower, ".tga"))
|
||||||
m_format = Bitmap::ETGA;
|
m_format = Bitmap::ETGA;
|
||||||
|
else if (endsWith(lower, ".bmp"))
|
||||||
|
m_format = Bitmap::EBMP;
|
||||||
else
|
else
|
||||||
Log(EError, "Cannot deduce the file type of '%s'!", m_filename.c_str());
|
Log(EError, "Cannot deduce the file type of '%s'!", m_filename.c_str());
|
||||||
|
|
||||||
|
@ -282,5 +284,5 @@ Shader *LDRTexture::createShader(Renderer *renderer) const {
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS_S(LDRTexture, false, Texture)
|
MTS_IMPLEMENT_CLASS_S(LDRTexture, false, Texture)
|
||||||
MTS_IMPLEMENT_CLASS(LDRTextureShader, false, Shader)
|
MTS_IMPLEMENT_CLASS(LDRTextureShader, false, Shader)
|
||||||
MTS_EXPORT_PLUGIN(LDRTexture, "LDR texture (JPG/TGA/PNG)");
|
MTS_EXPORT_PLUGIN(LDRTexture, "LDR texture (JPG/PNG/TGA/BMP)");
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
Loading…
Reference in New Issue