forked from bartvdbraak/blender
COLLADA: report #32237 fixed Camera exporter and Importer to use correct camera animation data
This commit is contained in:
parent
7d2190b79b
commit
f8a68d50f7
@ -106,7 +106,8 @@ void AnimationExporter::operator()(Object *ob)
|
||||
|
||||
if ((!strcmp(transformName, "lens")) ||
|
||||
(!strcmp(transformName, "ortho_scale")) ||
|
||||
(!strcmp(transformName, "clip_end")) || (!strcmp(transformName, "clip_start")))
|
||||
(!strcmp(transformName, "clip_end")) ||
|
||||
(!strcmp(transformName, "clip_start")))
|
||||
{
|
||||
dae_animation(ob, fcu, transformName, true);
|
||||
}
|
||||
@ -203,8 +204,10 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
|
||||
}
|
||||
|
||||
//axis names for colors
|
||||
else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") ||
|
||||
(!strcmp(transformName, "alpha")))
|
||||
else if (!strcmp(transformName, "color") ||
|
||||
!strcmp(transformName, "specular_color") ||
|
||||
!strcmp(transformName, "diffuse_color") ||
|
||||
!strcmp(transformName, "alpha"))
|
||||
{
|
||||
const char *axis_names[] = {"R", "G", "B"};
|
||||
if (fcu->array_index < 3)
|
||||
@ -212,8 +215,10 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
|
||||
}
|
||||
|
||||
//axis names for transforms
|
||||
else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
|
||||
(!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion")))
|
||||
else if (!strcmp(transformName, "location") ||
|
||||
!strcmp(transformName, "scale") ||
|
||||
!strcmp(transformName, "rotation_euler") ||
|
||||
!strcmp(transformName, "rotation_quaternion"))
|
||||
{
|
||||
const char *axis_names[] = {"X", "Y", "Z"};
|
||||
if (fcu->array_index < 3)
|
||||
@ -260,9 +265,13 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
|
||||
MEM_freeN(eul);
|
||||
MEM_freeN(eul_axis);
|
||||
}
|
||||
else if(!strcmp(transformName, "lens") && (ob->type == OB_CAMERA)) {
|
||||
output_id = create_lens_source_from_fcurve((Camera *) ob->data, COLLADASW::InputSemantic::OUTPUT, fcu, anim_id);
|
||||
}
|
||||
else {
|
||||
output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
|
||||
}
|
||||
|
||||
// create interpolations source
|
||||
std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);
|
||||
|
||||
@ -553,7 +562,7 @@ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNa
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
|
||||
void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_rotation, float *values, int *length)
|
||||
{
|
||||
switch (semantic) {
|
||||
case COLLADASW::InputSemantic::INPUT:
|
||||
@ -562,7 +571,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman
|
||||
break;
|
||||
case COLLADASW::InputSemantic::OUTPUT:
|
||||
*length = 1;
|
||||
if (rotation) {
|
||||
if (is_rotation) {
|
||||
values[0] = RAD2DEGF(bezt->vec[1][1]);
|
||||
}
|
||||
else {
|
||||
@ -578,7 +587,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
}
|
||||
else if (rotation) {
|
||||
else if (is_rotation) {
|
||||
values[1] = RAD2DEGF(bezt->vec[0][1]);
|
||||
}
|
||||
else {
|
||||
@ -594,7 +603,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
}
|
||||
else if (rotation) {
|
||||
else if (is_rotation) {
|
||||
values[1] = RAD2DEGF(bezt->vec[2][1]);
|
||||
}
|
||||
else {
|
||||
@ -654,6 +663,44 @@ std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemanti
|
||||
return source_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to create_source_from_fcurve, but adds conversion of lens
|
||||
* animation data from focal length to FOV.
|
||||
*/
|
||||
std::string AnimationExporter::create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id)
|
||||
{
|
||||
std::string source_id = anim_id + get_semantic_suffix(semantic);
|
||||
|
||||
COLLADASW::FloatSourceF source(mSW);
|
||||
source.setId(source_id);
|
||||
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
|
||||
source.setAccessorCount(fcu->totvert);
|
||||
|
||||
source.setAccessorStride(1);
|
||||
|
||||
COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
|
||||
add_source_parameters(param, semantic, false, "", false);
|
||||
|
||||
source.prepareToAppendValues();
|
||||
|
||||
for (unsigned int i = 0; i < fcu->totvert; i++) {
|
||||
float values[3]; // be careful!
|
||||
int length = 0;
|
||||
get_source_values(&fcu->bezt[i], semantic, false, values, &length);
|
||||
for (int j = 0; j < length; j++)
|
||||
{
|
||||
float val = RAD2DEGF(focallength_to_fov(values[j], cam->sensor_x));
|
||||
source.appendValues(val);
|
||||
}
|
||||
}
|
||||
|
||||
source.finish();
|
||||
|
||||
return source_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Currently called only to get OUTPUT source values ( if rotation and hence the axis is also specified )
|
||||
std::string AnimationExporter::create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
|
||||
{
|
||||
|
@ -133,6 +133,8 @@ protected:
|
||||
|
||||
std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
|
||||
|
||||
std::string create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id);
|
||||
|
||||
std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name);
|
||||
|
||||
std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name);
|
||||
|
@ -652,6 +652,51 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Lens animations must be stored in COLLADA by using FOV,
|
||||
* while blender internally uses focal length.
|
||||
* The imported animation curves must be converted appropriately.
|
||||
*/
|
||||
void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type)
|
||||
{
|
||||
char rna_path[100];
|
||||
if (animlist_map.find(listid) == animlist_map.end()) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
//anim_type has animations
|
||||
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
|
||||
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
|
||||
//all the curves belonging to the current binding
|
||||
std::vector<FCurve *> animcurves;
|
||||
for (unsigned int j = 0; j < bindings.getCount(); j++) {
|
||||
animcurves = curve_map[bindings[j].animation];
|
||||
|
||||
BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
|
||||
|
||||
modify_fcurve(&animcurves, rna_path, 0);
|
||||
std::vector<FCurve *>::iterator iter;
|
||||
//Add the curves of the current animation to the object
|
||||
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
|
||||
FCurve *fcu = *iter;
|
||||
|
||||
for (unsigned int i = 0; i < fcu->totvert; i++) {
|
||||
|
||||
double input_fov = fcu->bezt[i].vec[1][1];
|
||||
double xfov = (fov_type == CAMERA_YFOV) ? aspect * input_fov : input_fov;
|
||||
|
||||
// fov is in degrees, cam->lens is in millimiters
|
||||
double fov = fov_to_focallength(DEG2RADF(input_fov), cam->sensor_x);
|
||||
|
||||
fcu->bezt[i].vec[1][1] = fov;
|
||||
}
|
||||
|
||||
BLI_addtail(AnimCurves, fcu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node,
|
||||
COLLADAFW::Transformation *tm)
|
||||
{
|
||||
@ -796,6 +841,39 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the aspet ration from the Collada camera.
|
||||
*
|
||||
* Note:COLLADA allows to specify either XFov, or YFov alone.
|
||||
* In tghat case the aspect ratio can be determined from
|
||||
* the viewport aspect ratio (which is 1:1 ?)
|
||||
* XXX: check this: its probably wrong!
|
||||
* If both values are specified, then the aspect ration is simply xfov/yfov
|
||||
* and if aspect ratio is efined, then .. well then its that one.
|
||||
*/
|
||||
static const double get_aspect_ratio(const COLLADAFW::Camera *camera)
|
||||
{
|
||||
double aspect = camera->getAspectRatio().getValue();
|
||||
|
||||
if(aspect == 0)
|
||||
{
|
||||
const double yfov = camera->getYFov().getValue();
|
||||
|
||||
if(yfov == 0)
|
||||
aspect=1; // assume yfov and xfov are equal
|
||||
else
|
||||
{
|
||||
const double xfov = camera->getXFov().getValue();
|
||||
if (xfov==0)
|
||||
aspect = 1;
|
||||
else
|
||||
aspect = xfov / yfov;
|
||||
}
|
||||
}
|
||||
return aspect;
|
||||
}
|
||||
|
||||
|
||||
void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
|
||||
std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& root_map,
|
||||
std::multimap<COLLADAFW::UniqueId, Object *>& object_map,
|
||||
@ -924,10 +1002,11 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
|
||||
}
|
||||
|
||||
if (animType->camera != 0) {
|
||||
Camera *camera = (Camera *) ob->data;
|
||||
|
||||
if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID *)&camera->id, 1);
|
||||
else act = camera->adt->action;
|
||||
Camera *cam = (Camera *) ob->data;
|
||||
if (!cam->adt || !cam->adt->action)
|
||||
act = verify_adt_action((ID *)&cam->id, 1);
|
||||
else
|
||||
act = cam->adt->action;
|
||||
|
||||
ListBase *AnimCurves = &(act->curves);
|
||||
const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras();
|
||||
@ -938,13 +1017,15 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
|
||||
if ((animType->camera & CAMERA_XFOV) != 0) {
|
||||
const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov());
|
||||
const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
|
||||
Assign_float_animations(listid, AnimCurves, "lens");
|
||||
double aspect = get_aspect_ratio(camera);
|
||||
Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV);
|
||||
}
|
||||
|
||||
else if ((animType->camera & CAMERA_YFOV) != 0) {
|
||||
const COLLADAFW::AnimatableFloat *yfov = &(camera->getYFov());
|
||||
const COLLADAFW::UniqueId& listid = yfov->getAnimationList();
|
||||
Assign_float_animations(listid, AnimCurves, "lens");
|
||||
double aspect = get_aspect_ratio(camera);
|
||||
Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV);
|
||||
}
|
||||
|
||||
else if ((animType->camera & CAMERA_XMAG) != 0) {
|
||||
|
@ -165,6 +165,7 @@ public:
|
||||
|
||||
void Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type);
|
||||
void Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type);
|
||||
void Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type);
|
||||
|
||||
int setAnimType ( const COLLADAFW::Animatable * prop, int type, int addition);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user