diff --git a/data/schema/scene.xsd b/data/schema/scene.xsd
index 6db9ba99..bd8fe97a 100644
--- a/data/schema/scene.xsd
+++ b/data/schema/scene.xsd
@@ -323,15 +323,9 @@
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/doc/format.tex b/doc/format.tex
index ce204bea..6fabc689 100644
--- a/doc/format.tex
+++ b/doc/format.tex
@@ -271,10 +271,12 @@ choices are available:
\begin{xml}
\end{xml}
-\item LookAt transformations --- this is useful for setting up the camera. The \textbf{o} coordinates
-provide the camera origin, \textbf{t} specifies the target and \textbf{u} is the ``up'' direction.
+\item LookAt transformations --- this is primarily useful for setting up cameras (and spot lights). The \code{origin} coordinates
+specify the camera origin, \code{target} is the point that the camera will look at, and the
+(optional) \code{up} parameter determines the ``upward'' direction in the final rendered image.
+The \code{up} parameter is not needed for spot lights.
\begin{xml}
-
+
\end{xml}
\end{itemize}
Cordinates that are zero (for \code{translate} and \code{rotate}) or one (for \code{scale})
diff --git a/src/converter/collada.cpp b/src/converter/collada.cpp
index 178febd3..b81a1e3d 100644
--- a/src/converter/collada.cpp
+++ b/src/converter/collada.cpp
@@ -987,7 +987,7 @@ void loadLight(ColladaContext &ctx, Transform transform, domLight &light) {
ctx.os << "\t" << endl;
ctx.os << "\t\t" << endl << endl;
ctx.os << "\t\t" << endl;
- ctx.os << "\t\t\t" << endl;
+ ctx.os << "\t\t\t" << endl;
ctx.os << "\t\t" << endl << endl;
ctx.os << "\t" << endl << endl;
}
@@ -1011,7 +1011,7 @@ void loadLight(ColladaContext &ctx, Transform transform, domLight &light) {
ctx.os << "\t\t" << endl;
ctx.os << "\t\t" << endl << endl;
ctx.os << "\t\t" << endl;
- ctx.os << "\t\t\t" << endl;
+ ctx.os << "\t\t\t" << endl;
ctx.os << "\t\t" << endl;
ctx.os << "\t" << endl << endl;
}
diff --git a/src/librender/scenehandler.cpp b/src/librender/scenehandler.cpp
index d10c718e..b83220b5 100644
--- a/src/librender/scenehandler.cpp
+++ b/src/librender/scenehandler.cpp
@@ -225,17 +225,31 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
Float angle = parseFloat(name, context.attributes["angle"]);
m_transform = Transform::rotate(Vector(x, y, z), angle) * m_transform;
} else if (name == "lookAt") {
- Float ox = parseFloat(name, context.attributes["ox"]);
- Float oy = parseFloat(name, context.attributes["oy"]);
- Float oz = parseFloat(name, context.attributes["oz"]);
- Float tx = parseFloat(name, context.attributes["tx"]);
- Float ty = parseFloat(name, context.attributes["ty"]);
- Float tz = parseFloat(name, context.attributes["tz"]);
- Float ux = parseFloat(name, context.attributes["ux"], 0);
- Float uy = parseFloat(name, context.attributes["uy"], 0);
- Float uz = parseFloat(name, context.attributes["uz"], 0);
- Point o(ox, oy, oz), t(tx, ty, tz);
- Vector u(ux, uy, uz);
+ std::vector tokens = tokenize(context.attributes["origin"], ", ");
+ if (tokens.size() != 3)
+ XMLLog(EError, ": invalid 'origin' argument");
+ Point o(
+ parseFloat(name, tokens[0]),
+ parseFloat(name, tokens[1]),
+ parseFloat(name, tokens[2]));
+ tokens = tokenize(context.attributes["target"], ", ");
+ if (tokens.size() != 3)
+ XMLLog(EError, ": invalid 'target' argument");
+ Point t(
+ parseFloat(name, tokens[0]),
+ parseFloat(name, tokens[1]),
+ parseFloat(name, tokens[2]));
+ Vector u(0.0f);
+ tokens = tokenize(context.attributes["up"], ", ");
+ if (tokens.size() == 3)
+ u = Vector(
+ parseFloat(name, tokens[0]),
+ parseFloat(name, tokens[1]),
+ parseFloat(name, tokens[2]));
+ else if (tokens.size() == 0)
+ ;
+ else
+ XMLLog(EError, ": invalid 'up' argument");
if (u.lengthSquared() == 0) {
/* If 'up' was not specified, use an arbitrary axis */
diff --git a/src/qtgui/save.cpp b/src/qtgui/save.cpp
index 15fbd085..2485b95e 100644
--- a/src/qtgui/save.cpp
+++ b/src/qtgui/save.cpp
@@ -172,15 +172,9 @@ void saveScene(QWidget *parent, SceneContext *ctx, const QString &targetFile) {
}
t = p + direction;
- lookAt.setAttribute("ox", QString::number(p.x));
- lookAt.setAttribute("oy", QString::number(p.y));
- lookAt.setAttribute("oz", QString::number(p.z));
- lookAt.setAttribute("tx", QString::number(t.x));
- lookAt.setAttribute("ty", QString::number(t.y));
- lookAt.setAttribute("tz", QString::number(t.z));
- lookAt.setAttribute("ux", QString::number(u.x));
- lookAt.setAttribute("uy", QString::number(u.y));
- lookAt.setAttribute("uz", QString::number(u.z));
+ lookAt.setAttribute("origin", QString("%1, %2, %3").arg(p.x).arg(p.y).arg(p.z));
+ lookAt.setAttribute("up", QString("%1, %2, %3").arg(u.x).arg(u.y).arg(u.z));
+ lookAt.setAttribute("target", QString("%1, %2, %3").arg(t.x).arg(t.y).arg(t.z));
// ====================================================================
// Serialize the sampler configuration
@@ -331,7 +325,6 @@ void saveScene(QWidget *parent, SceneContext *ctx, const QString &targetFile) {
Beware: the code below is tailored to Qt's
output and won't work on arbitrary XML files */
QString textContent = doc.toString();
- cout << qPrintable(textContent) << endl;
QTextStream input(&textContent);
QTextStream output(&file);
QRegExp