initial support for importing animation tracks

metadata
Wenzel Jakob 2010-11-15 16:05:50 +01:00
parent 36e9571e9f
commit 710890d894
11 changed files with 195 additions and 10 deletions

View File

@ -0,0 +1,67 @@
/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2010 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__ANIMATION_TRACK_H)
#define __ANIMATION_TRACK_H
#include <mitsuba/mitsuba.h>
MTS_NAMESPACE_BEGIN
template <typename T> class AnimationTrack {
public:
enum EType {
EInvalid = 0,
ELocationX, ELocationY, ELocationZ, ELocationXYZ,
EScaleX, EScaleY, EScaleZ, EScaleXYZ,
ERotationX, ERotationY, ERotationZ, ERotationXYZ
};
AnimationTrack(EType type, size_t nKeyframes)
: m_type(type), m_times(nKeyframes), m_values(nKeyframes) { }
/// Return the type of this track
inline EType getType() const { return m_type; }
/// Return the number of keyframes
inline size_t getSize() const { return m_times.size(); }
/// Set the time value of a certain keyframe
inline void setTime(size_t idx, Float time) { m_times[idx] = time; }
/// Return the time value of a certain keyframe
inline Float getTime(size_t idx) const { return m_times[idx]; }
/// Set the value of a certain keyframe
inline void setValue(size_t idx, const T &value) { m_values[idx] = value; }
/// Return the value of a certain keyframe
inline const T &getValue(size_t idx) const { return m_values[idx]; }
/// Evaluate the animation track at an arbitrary time value
inline T lookup(Float time) const {
}
private:
EType m_type;
std::vector<Float> m_times;
std::vector<T> m_values;
};
MTS_NAMESPACE_END
#endif /* __ANIMATION_TRACK_H */

View File

@ -20,6 +20,7 @@
#include <mitsuba/render/trimesh.h>
#include <mitsuba/core/fresolver.h>
#include <mitsuba/core/fstream.h>
#include <mitsuba/render/track.h>
#include <dom/domCOLLADA.h>
#include <dae.h>
#include <dae/daeErrorHandler.h>
@ -35,14 +36,21 @@
#include <GL/glu.h>
#endif
#ifndef WIN32
#define __stdcall
#endif
#include "converter.h"
typedef AnimationTrack<Float> FloatTrack;
typedef std::map<std::string, std::string> StringMap;
typedef std::map<std::string, int> RefCountMap;
typedef std::map<std::string, FloatTrack *> AnimationMap;
struct ColladaContext {
GeometryConverter *cvt;
RefCountMap refCountMap;
AnimationMap animations;
std::set<std::string> serializedGeometry;
fs::path texturesDirectory;
fs::path meshesDirectory;
@ -153,6 +161,7 @@ VertexData *fetchVertexData(Transform transform,
for (size_t i=0; i<inputs.getCount(); ++i) {
int offsetInStream = (int) inputs[i]->getOffset(),
offset = offsetInStream;
daeURI &sourceRef = inputs[i]->getSource();
sourceRef.resolveElement();
domSource *source = daeSafeCast<domSource>(sourceRef.getElement());
@ -309,7 +318,6 @@ struct triangle_key_order : public std::binary_function<SimpleTriangle, SimpleTr
}
};
class CustomErrorHandler : public daeErrorHandler {
public:
void handleError(daeString msg) {
@ -1287,9 +1295,111 @@ void computeRefCounts(ColladaContext &ctx, domNode &node) {
}
}
#ifndef WIN32
#define __stdcall
#endif
void loadAnimation(ColladaContext &ctx, domAnimation &anim) {
std::string identifier;
if (anim.getId() != NULL) {
identifier = anim.getId();
} else {
if (anim.getName() != NULL) {
identifier = anim.getName();
} else {
static int unnamedCtr = 0;
identifier = formatString("unnamedAnimation_%i", unnamedCtr);
}
}
SLog(EInfo, "Loading animation \"%s\" ..", identifier.c_str());
domChannel_Array &channels = anim.getChannel_array();
for (size_t i=0; i<channels.getCount(); ++i) {
domChannel *channel = channels[i];
std::vector<std::string> target = tokenize(channel->getTarget(), "./");
SAssertEx(target.size() == 3, "Encountered an unknown animation channel identifier!");
daeURI &sourceRef = channel->getSource();
sourceRef.resolveElement();
domSampler *sampler = daeSafeCast<domSampler>(sourceRef.getElement());
if (!sampler)
SLog(EError, "Referenced animation sampler not found!");
const domInputLocal_Array &inputs = sampler->getInput_array();
FloatTrack *track = NULL;
FloatTrack::EType trackType = FloatTrack::EInvalid;
boost::to_lower(target[1]);
boost::to_lower(target[2]);
if (target[1] == "location") {
if (target[2] == "x") {
trackType = FloatTrack::ELocationX;
} else if (target[2] == "y") {
trackType = FloatTrack::ELocationY;
} else if (target[3] == "z") {
trackType = FloatTrack::ELocationZ;
}
} else if (target[1] == "scale") {
if (target[2] == "x") {
trackType = FloatTrack::EScaleX;
} else if (target[2] == "y") {
trackType = FloatTrack::EScaleY;
} else if (target[3] == "z") {
trackType = FloatTrack::EScaleZ;
}
} else if (target[1] == "rotationx" && target[2] == "angle") {
trackType = FloatTrack::ERotationX;
} else if (target[1] == "rotationy" && target[2] == "angle") {
trackType = FloatTrack::ERotationY;
} else if (target[1] == "rotationz" && target[2] == "angle") {
trackType = FloatTrack::ERotationZ;
}
if (trackType == FloatTrack::EInvalid) {
SLog(EWarn, "Skipping unsupported animation track of type %s.%s",
target[1].c_str(), target[2].c_str());
continue;
}
for (size_t j=0; j<inputs.getCount(); ++j) {
sourceRef = inputs[j]->getSource();
sourceRef.resolveElement();
domSource *source = daeSafeCast<domSource>(sourceRef.getElement());
if (!source)
SLog(EError, "Referenced animation source not found!");
std::string semantic = inputs[j]->getSemantic();
domSource::domTechnique_common *techniqueCommon = source->getTechnique_common();
if (!techniqueCommon)
SLog(EError, "Data source does not have a <technique_common> tag!");
domAccessor *accessor = techniqueCommon->getAccessor();
if (!accessor)
SLog(EError, "Data source does not have a <accessor> tag!");
unsigned int nParams = (unsigned int) accessor->getParam_array().getCount(),
stride = (unsigned int) accessor->getStride();
size_t size = (size_t) accessor->getCount();
if (stride != 1 || nParams != 1) {
/// Only single-valued tracks are supported for now
SLog(EError, "Encountered a multi-valued animation track.");
}
if (!track)
track = new FloatTrack(trackType, size);
else
SAssert(track->getSize() == size);
if (semantic == "INPUT") {
domListOfFloats &floatArray = source->getFloat_array()->getValue();
for (size_t i=0; i<size; ++i)
track->setTime(i, floatArray[i]);
} else if (semantic == "OUTPUT") {
domListOfFloats &floatArray = source->getFloat_array()->getValue();
for (size_t i=0; i<size; ++i)
track->setValue(i, floatArray[i]);
} else if (semantic == "INTERPOLATION") {
/// Ignored for now
} else {
SLog(EWarn, "Encountered an unsupported semantic: \"%s\"", semantic.c_str());
}
}
if (track)
ctx.animations.insert(AnimationMap::value_type(target[0], track));
}
}
GLvoid __stdcall tessBegin(GLenum type) {
SAssert(type == GL_TRIANGLES);
@ -1338,15 +1448,12 @@ GLvoid __stdcall tessCombine(GLdouble coords[3], void *vertex_data[4],
*outData = result;
}
GLvoid __stdcall tessEnd() {
}
GLvoid __stdcall tessEnd() { }
GLvoid __stdcall tessEdgeFlag(GLboolean) { }
GLvoid __stdcall tessError(GLenum error) {
SLog(EError, "The GLU tesselator generated an error: %s!", gluErrorString(error));
}
GLvoid __stdcall tessEdgeFlag(GLboolean) {
}
void GeometryConverter::convertCollada(const fs::path &inputFile,
std::ostream &os,
@ -1404,12 +1511,23 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
for (size_t j=0; j<materials.getCount(); ++j)
loadMaterial(ctx, *materials.get(j));
}
domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array();
for (size_t i=0; i<libraryAnimations.getCount(); ++i) {
domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array();
for (size_t j=0; j<animations.getCount(); ++j)
loadAnimation(ctx, *animations[j]);
}
for (size_t i=0; i<nodes.getCount(); ++i)
computeRefCounts(ctx, *nodes[i]);
for (size_t i=0; i<nodes.getCount(); ++i)
loadNode(ctx, Transform(), *nodes[i], "");
for (AnimationMap::iterator it = ctx.animations.begin();
it != ctx.animations.end(); ++it)
delete it->second;
os << "</scene>" << endl;

View File

@ -61,7 +61,7 @@ class lamps(DataButtonsPanel, property_group_renderer, bpy.types.Panel):
else:
layout.prop(lamp.mitsuba_lamp, "envmap_file", text="HDRI file")
layout.prop(lamp.mitsuba_lamp, "intensity", text="Intensity")
layout.prop(lamp.mitsuba_lamp, "sampling_weight", text = "Sampling weight")
layout.prop(lamp.mitsuba_lamp, "samplingWeight", text = "Sampling weight")
# SPOT LAMP: Blender Properties
if lamp.type == 'SPOT':