vast collada importer improvements, incomplete bmp loading support
parent
715a854199
commit
02c47237a7
|
@ -18,6 +18,7 @@ public:
|
|||
EPNG = 0,
|
||||
EEXR,
|
||||
ETGA,
|
||||
EBMP,
|
||||
EJPEG
|
||||
};
|
||||
|
||||
|
@ -104,6 +105,9 @@ protected:
|
|||
|
||||
/// Load a file stored using the TGA file format
|
||||
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
|
||||
void loadJPEG(Stream *stream);
|
||||
|
|
|
@ -111,6 +111,9 @@ public:
|
|||
/// Return the logger's formatter implementation
|
||||
inline Formatter *getFormatter() { return m_formatter; }
|
||||
|
||||
/// Return the number of warnings reported so far
|
||||
inline size_t getWarningCount() const { return m_warningCount; }
|
||||
|
||||
/// Initialize logging
|
||||
static void staticInitialization();
|
||||
|
||||
|
@ -126,6 +129,7 @@ protected:
|
|||
ref<Formatter> m_formatter;
|
||||
ref<Mutex> m_mutex;
|
||||
std::vector<Appender *> m_appenders;
|
||||
size_t m_warningCount;
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
|
|
@ -101,18 +101,22 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
|||
result->typeToOffset.resize(ELast);
|
||||
for (int i=0; i<ELast; ++i)
|
||||
result->typeToOffset[i] = -1;
|
||||
int vertInputIndex = 0;
|
||||
|
||||
for (size_t i=0; i<inputs.getCount(); ++i) {
|
||||
int offset = (int) inputs[i]->getOffset();
|
||||
daeURI &sourceRef = inputs[i]->getSource();
|
||||
sourceRef.resolveElement();
|
||||
domSource *source = daeSafeCast<domSource>(sourceRef.getElement());
|
||||
std::string semantic = inputs[i]->getSemantic();
|
||||
|
||||
if (!strcmp(inputs[i]->getSemantic(), "VERTEX")) {
|
||||
SAssert(vertInputs.getCount() == 1);
|
||||
sourceRef = vertInputs[0]->getSource();
|
||||
if (semantic == "VERTEX") {
|
||||
sourceRef = vertInputs[vertInputIndex]->getSource();
|
||||
sourceRef.resolveElement();
|
||||
source = daeSafeCast<domSource>(sourceRef.getElement());
|
||||
semantic = vertInputs[vertInputIndex]->getSemantic();
|
||||
if (++vertInputIndex < (int) vertInputs.getCount())
|
||||
--i;
|
||||
}
|
||||
|
||||
domListOfFloats &floatArray = source->getFloat_array()->getValue();
|
||||
|
@ -128,14 +132,13 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
|||
SAssert(nParams <= 4);
|
||||
|
||||
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)
|
||||
target[j][k] = (Float) floatArray[j*stride+k];
|
||||
}
|
||||
|
||||
result->data[offset] = target;
|
||||
|
||||
if (!strcmp(inputs[i]->getSemantic(), "VERTEX")) {
|
||||
if (semantic == "POSITION") {
|
||||
SAssert(accessor->getStride() == 3);
|
||||
SAssert(result->typeToOffset[EPosition] == -1);
|
||||
result->offsetToType[offset] = EPosition;
|
||||
|
@ -143,28 +146,28 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
|||
result->glPos = new GLdouble[3*size];
|
||||
for (int k=0; k<3*size; ++k)
|
||||
result->glPos[k] = floatArray[k];
|
||||
} else if (!strcmp(inputs[i]->getSemantic(), "NORMAL")) {
|
||||
} else if (semantic == "NORMAL") {
|
||||
SAssert(accessor->getStride() == 3);
|
||||
SAssert(result->typeToOffset[ENormal] == -1);
|
||||
result->hasNormals = true;
|
||||
result->offsetToType[offset] = ENormal;
|
||||
result->typeToOffset[ENormal] = offset;
|
||||
} else if (!strcmp(inputs[i]->getSemantic(), "TEXCOORD")) {
|
||||
} else if (semantic == "TEXCOORD") {
|
||||
SAssert(accessor->getStride() == 2 || accessor->getStride() == 3);
|
||||
if (result->typeToOffset[EUV] == -1) {
|
||||
result->hasUVs = true;
|
||||
result->offsetToType[offset] = EUV;
|
||||
result->typeToOffset[EUV] = offset;
|
||||
} 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")) {
|
||||
SLog(EWarn, "Found per-vertex colors - ignoring. Please bake into a texture (Lighting/shading -> Batch Bake in Maya)");
|
||||
} else if (semantic == "COLOR") {
|
||||
SLog(EWarn, "Found per-vertex colors - ignoring. Please bake into a texture "
|
||||
"(Lighting/shading -> Batch Bake in Maya)");
|
||||
result->offsetToType[offset] = EVertexColors;
|
||||
result->typeToOffset[EVertexColors] = offset;
|
||||
} else {
|
||||
SLog(EError, "Encountered an unknown source semantic: %s",
|
||||
inputs[i]->getSemantic());
|
||||
SLog(EError, "Encountered an unknown source semantic: %s", semantic.c_str());
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
std::string geomName;
|
||||
if (geom.getName() != NULL) {
|
||||
geomName = geom.getName();
|
||||
std::string identifier;
|
||||
if (geom.getId() != NULL) {
|
||||
identifier = geom.getId();
|
||||
} else {
|
||||
if (geom.getId() != NULL) {
|
||||
geomName = geom.getId();
|
||||
if (geom.getName() != NULL) {
|
||||
identifier = geom.getName();
|
||||
} else {
|
||||
static int unnamedGeomCtr = 0;
|
||||
geomName = formatString("unnamedGeom_%i", unnamedGeomCtr);
|
||||
static int unnamedCtr = 0;
|
||||
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();
|
||||
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();
|
||||
|
||||
std::string xmlName = nodeName + std::string("_") + geom.getId();
|
||||
std::string xmlName = prefixName + identifier;
|
||||
int geomIndex = 0;
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
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) {
|
||||
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;
|
||||
|
||||
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!");
|
||||
|
||||
domProfile_COMMON::domTechnique::domPhong* phong = technique->getPhong();
|
||||
domProfile_COMMON::domTechnique::domBlinn* blinn = technique->getBlinn();
|
||||
domProfile_COMMON::domTechnique::domLambert* lambert = technique->getLambert();
|
||||
domProfile_COMMON::domTechnique::domConstant* constant = technique->getConstant();
|
||||
|
||||
if (phong) {
|
||||
domCommon_color_or_texture_type* diffuse = phong->getDiffuse();
|
||||
|
@ -499,12 +515,12 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
|||
isDiffuse = true;
|
||||
}
|
||||
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, true);
|
||||
os << "\t</bsdf>" << endl << endl;
|
||||
} 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=\"diffuseReflectance\" value=\"1\"/>" << endl;
|
||||
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, false);
|
||||
|
@ -517,17 +533,65 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
|||
}
|
||||
} else if (lambert) {
|
||||
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, true);
|
||||
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 {
|
||||
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) {
|
||||
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;
|
||||
|
||||
// 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)
|
||||
notQuadratic = true;
|
||||
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();
|
||||
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<transform name=\"toWorld\">" << 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();
|
||||
if (directional) {
|
||||
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<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;
|
||||
|
@ -591,12 +655,12 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
|
|||
if (spot->getQuadratic_attenuation() && spot->getQuadratic_attenuation()->getValue() != 1)
|
||||
notQuadratic = true;
|
||||
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();
|
||||
Float falloffAngle = 180.0f;
|
||||
if (spot->getFalloff_angle())
|
||||
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<float name=\"cutoffAngle\" value=\"" << falloffAngle/2 << "\"/>" << endl << 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();
|
||||
if (ambient) {
|
||||
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</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,
|
||||
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());
|
||||
if (fileToId.find(filename) != fileToId.end()) {
|
||||
idToTexture[image.getId()] = fileToId[filename];
|
||||
idToTexture[identifier] = fileToId[filename];
|
||||
return;
|
||||
}
|
||||
|
||||
idToTexture[image.getId()] = image.getId();
|
||||
fileToId[filename] = image.getId();
|
||||
idToTexture[identifier] = identifier;
|
||||
fileToId[filename] = identifier;
|
||||
|
||||
boost::filesystem::path path = boost::filesystem::path(filename, boost::filesystem::native);
|
||||
std::string targetPath = textureDir + path.leaf();
|
||||
|
@ -655,13 +731,25 @@ void loadImage(GeometryConverter *cvt, std::ostream &os, const std::string &text
|
|||
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</texture>" << endl << endl;
|
||||
}
|
||||
|
||||
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;
|
||||
int xres=768;
|
||||
|
||||
|
@ -683,7 +771,7 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
|||
xres = cvt->m_xres;
|
||||
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()->
|
||||
|
@ -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()) {
|
||||
Float xFov = persp->getXfov()->getValue();
|
||||
Float xFov = (Float) persp->getXfov()->getValue();
|
||||
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"
|
||||
" - 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
|
||||
os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
|
||||
} 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) {
|
||||
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.");
|
||||
|
@ -753,19 +841,19 @@ void loadCamera(GeometryConverter *cvt, Transform transform, std::ostream &os, d
|
|||
}
|
||||
|
||||
void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
||||
domNode &node, const std::string &meshesDir) {
|
||||
std::string nodeName;
|
||||
if (node.getName() != NULL) {
|
||||
nodeName = node.getName();
|
||||
domNode &node, std::string prefixName, const std::string &meshesDir) {
|
||||
std::string identifier;
|
||||
if (node.getId() != NULL) {
|
||||
identifier = node.getId();
|
||||
} else {
|
||||
if (node.getId() != NULL) {
|
||||
nodeName = node.getId();
|
||||
if (node.getName() != NULL) {
|
||||
identifier = node.getName();
|
||||
} else {
|
||||
static int unnamedNodeCtr = 0;
|
||||
nodeName = formatString("unnamedNode_%i", unnamedNodeCtr);
|
||||
static int unnamedCtr = 0;
|
||||
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();
|
||||
/* Parse transformations */
|
||||
|
@ -824,7 +912,7 @@ void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
|||
|
||||
if (!geom)
|
||||
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 */
|
||||
|
@ -850,7 +938,7 @@ void loadNode(GeometryConverter *cvt, Transform transform, std::ostream &os,
|
|||
/* Recursively iterate through sub-nodes */
|
||||
domNode_Array &nodes = node.getNode_array();
|
||||
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 */
|
||||
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());
|
||||
if (!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)
|
||||
loadNode(this, Transform(), os, *nodes[i], meshesDirectory);
|
||||
loadNode(this, Transform(), os, *nodes[i], "", meshesDirectory);
|
||||
|
||||
os << "</scene>" << endl;
|
||||
|
||||
|
|
|
@ -137,7 +137,15 @@ int colladaMain(int argc, char **argv) {
|
|||
converter.setMapSmallerSide(mapSmallerSide);
|
||||
converter.setSamplesPerPixel(samplesPerPixel);
|
||||
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] : "");
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -146,19 +146,21 @@ Bitmap::Bitmap(int width, int height, int bpp)
|
|||
m_gamma = -1.0f; // sRGB
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(EFileFormat format, Stream *stream) : m_data(NULL) {
|
||||
if (format == EPNG)
|
||||
loadPNG(stream);
|
||||
else if (format == ETGA)
|
||||
loadTGA(stream);
|
||||
else if (format == EJPEG)
|
||||
loadJPEG(stream);
|
||||
else if (format == EEXR)
|
||||
loadEXR(stream);
|
||||
else if (format == ETGA)
|
||||
loadTGA(stream);
|
||||
else if (format == EBMP)
|
||||
loadBMP(stream);
|
||||
else
|
||||
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) {
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
@ -309,7 +378,7 @@ void Bitmap::loadPNG(Stream *stream) {
|
|||
&colortype, &interlacetype, &compressiontype, &filtertype);
|
||||
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));
|
||||
|
||||
rows = new png_bytep[m_height];
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
Logger::Logger(ELogLevel level)
|
||||
: m_logLevel(level) {
|
||||
: m_logLevel(level), m_warningCount(0) {
|
||||
m_mutex = new Mutex();
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,8 @@ void Logger::log(ELogLevel level, const Class *theClass,
|
|||
|
||||
if (level < EError) {
|
||||
m_mutex->lock();
|
||||
if (level >= EWarn)
|
||||
m_warningCount++;
|
||||
for (unsigned int i=0; i<m_appenders.size(); ++i)
|
||||
m_appenders[i]->append(level, text);
|
||||
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) {
|
||||
/* Calculate smooth normals if there aren't any */
|
||||
int zeroArea = 0, zeroNormals = 0;
|
||||
|
||||
if (!hasNormals) {
|
||||
for (unsigned int i=0; i<m_vertexCount; i++)
|
||||
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();
|
||||
if (length != 0)
|
||||
n /= length;
|
||||
else if (complain)
|
||||
Log(EWarn, "Invalid geometry - cannot calculate normals");
|
||||
else
|
||||
zeroArea++;
|
||||
m_vertexBuffer[m_triangles[i].idx[0]].n += n;
|
||||
m_vertexBuffer[m_triangles[i].idx[1]].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 (unsigned int i=0; i<m_vertexCount; i++) {
|
||||
if (m_vertexBuffer[i].n.isZero()) {
|
||||
if (complain)
|
||||
Log(EWarn, "Mesh has zero normals!");
|
||||
zeroNormals++;
|
||||
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
||||
}
|
||||
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].dpdv = Vector(0.0, 0.0f, 0.0f);
|
||||
if (m_vertexBuffer[i].n.isZero()) {
|
||||
if (complain)
|
||||
Log(EWarn, "Mesh has zero normals!");
|
||||
zeroNormals++;
|
||||
m_vertexBuffer[i].n = Normal(1, 0, 0);
|
||||
}
|
||||
sharers[i] = 0;
|
||||
|
@ -230,8 +230,8 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
|||
Float length = n.length();
|
||||
if (length != 0)
|
||||
n /= length;
|
||||
else if (complain)
|
||||
Log(EWarn, "Mesh contains invalid geometry!");
|
||||
else
|
||||
zeroArea++;
|
||||
dpdu = cross(n, dpdv);
|
||||
|
||||
if (dpdu.length() == 0.0f) {
|
||||
|
@ -246,8 +246,8 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
|||
Float length = n.length();
|
||||
if (length != 0)
|
||||
n /= length;
|
||||
else if (complain)
|
||||
Log(EWarn, "Mesh contains invalid geometry!");
|
||||
else
|
||||
zeroArea++;
|
||||
dpdv = cross(dpdu, n);
|
||||
|
||||
if (dpdv.length() == 0.0f) {
|
||||
|
@ -265,6 +265,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
|||
m_vertexBuffer[idx2].dpdv += dpdv;
|
||||
sharers[idx0]++; sharers[idx1]++; sharers[idx2]++;
|
||||
}
|
||||
|
||||
/* Orthogonalization + Normalization pass */
|
||||
for (unsigned int i=0; i<m_vertexCount; i++) {
|
||||
Vector dpdu = m_vertexBuffer[i].dpdu;
|
||||
|
@ -286,6 +287,10 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
|
|||
}
|
||||
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 {
|
||||
|
|
|
@ -112,6 +112,9 @@ void ImportDialog::accept() {
|
|||
if (!m_resolver->contains(filePath))
|
||||
m_resolver->addPath(filePath);
|
||||
|
||||
const Logger *logger = Thread::getThread()->getLogger();
|
||||
size_t initialWarningCount = logger->getWarningCount();
|
||||
|
||||
ref<SceneImporter> importingThread = new SceneImporter(this,
|
||||
m_resolver, sourceFile.toStdString(), directory.toStdString(),
|
||||
targetScene.toStdString(), adjustmentFile.toStdString(),
|
||||
|
@ -122,15 +125,22 @@ void ImportDialog::accept() {
|
|||
QCoreApplication::processEvents();
|
||||
importingThread->wait(20);
|
||||
}
|
||||
|
||||
importingThread->join();
|
||||
|
||||
dialog->hide();
|
||||
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()));
|
||||
else
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Scene Import"),
|
||||
tr("Conversion failed -- please see the log for details."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
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 {
|
||||
public:
|
||||
|
@ -30,6 +30,8 @@ public:
|
|||
m_format = Bitmap::EPNG;
|
||||
else if (endsWith(lower, ".tga"))
|
||||
m_format = Bitmap::ETGA;
|
||||
else if (endsWith(lower, ".bmp"))
|
||||
m_format = Bitmap::EBMP;
|
||||
else
|
||||
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(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
|
||||
|
|
Loading…
Reference in New Issue