author Joerg Mueller Mon, 20 Jun 2011 22:55:18 +0000 (22:55 +0000) committer Joerg Mueller Mon, 20 Jun 2011 22:55:18 +0000 (22:55 +0000)
20 files changed:
1  2
release/scripts/modules/bpy_types.py
release/scripts/startup/bl_operators/nla.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/constraint.c
source/blender/editors/interface/resources.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/transform/transform_conversions.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_userdef.c
source/gameengine/Converter/BL_ActionActuator.cpp

@@@ -20,7 -20,6 +20,6 @@@

from _bpy import types as bpy_types
import _bpy
- from mathutils import Vector

StructRNA = bpy_types.Struct.__bases__[0]
StructMetaPropGroup = _bpy.StructMetaPropGroup
@@@ -144,18 -143,21 +143,21 @@@ class _GenericBone
def x_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
+         from mathutils import Vector
return Vector((1.0, 0.0, 0.0)) * self.matrix.to_3x3()

@property
def y_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
+         from mathutils import Vector
return Vector((0.0, 1.0, 0.0)) * self.matrix.to_3x3()

@property
def z_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
+         from mathutils import Vector
return Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()

@property
@@@ -409,16 -411,6 +411,16 @@@ class Text(bpy_types.ID)
TypeMap = {}

+class Sound(bpy_types.ID):
+    __slots__ = ()
+
+    @property
+    def factory(self):
+        """The aud.Factory object of the sound."""
+        import aud
+        return aud._sound_from_pointer(self.as_pointer())
+
+
class RNAMeta(type):
def __new__(cls, name, bases, classdict, **args):
result = type.__new__(cls, name, bases, classdict)
#
# ##### END GPL LICENSE BLOCK #####

- # <pep8 compliant>
+ # <pep8-80 compliant>

import bpy

- def pose_info():
+ def pose_frame_info(obj):
from mathutils import Matrix

info = {}

-     obj = bpy.context.object
pose = obj.pose

pose_items = pose.bones.items()
@@@ -51,7 -50,6 +50,6 @@@
except:
binfo["matrix_pose_inv"] = Matrix()

-         print(binfo["matrix_pose"])
info[name] = binfo

for name, pbone in pose_items:
matrix = binfo_parent["matrix_pose_inv"] * matrix
rest_matrix = binfo_parent["matrix_local_inv"] * rest_matrix

-         matrix = rest_matrix.inverted() * matrix
+         binfo["matrix_key"] = rest_matrix.inverted() * matrix
+     return info

-         binfo["matrix_key"] = matrix.copy()

+ def obj_frame_info(obj):
+     info = {}
+     # parent = obj.parent
+     info["matrix_key"] = obj.matrix_local.copy()
return info

- def bake(frame_start, frame_end, step=1, only_selected=False):
+ def bake(frame_start,
+          frame_end, step=1,
+          only_selected=False,
+          do_pose=True,
+          do_object=True,
+          do_constraint_clear=False,
+          ):
scene = bpy.context.scene
obj = bpy.context.object
pose = obj.pose
+     frame_back = scene.frame_current
+     if pose is None:
+         do_pose = False

-     info_ls = []
+     if do_pose is None and do_object is None:
+         return None
+     pose_info = []
+     obj_info = []

frame_range = range(frame_start, frame_end + 1, step)

-     # could spped this up by applying steps here too...
+     # -------------------------------------------------------------------------
+     # Collect transformations
+
+     # could speed this up by applying steps here too...
for f in frame_range:
scene.frame_set(f)

-         info = pose_info()
-         info_ls.append(info)
+         if do_pose:
+             pose_info.append(pose_frame_info(obj))
+         if do_object:
+             obj_info.append(obj_frame_info(obj))
f += 1

+     # -------------------------------------------------------------------------
+     # Create action
+     # incase animation data hassnt been created
+     atd = obj.animation_data_create()
action = bpy.data.actions.new("Action")
+     atd.action = action

-     bpy.context.object.animation_data.action = action
+     if do_pose:
+         pose_items = pose.bones.items()
+     else:
+         pose_items = []  # skip

-     pose_items = pose.bones.items()
+     # -------------------------------------------------------------------------
+     # Apply transformations to action

-     for name, pbone in pose_items:
+     # pose
+     for name, pbone in (pose_items if do_pose else ()):
if only_selected and not pbone.bone.select:
continue

+         if do_constraint_clear:
+             while pbone.constraints:
+                 pbone.constraints.remove(pbone.constraints[0])
for f in frame_range:
-             matrix = info_ls[int((f - frame_start) / step)][name]["matrix_key"]
+             matrix = pose_info[(f - frame_start) // step][name]["matrix_key"]

-             #pbone.location = matrix.to_translation()
-             #pbone.rotation_quaternion = matrix.to_quaternion()
+             # pbone.location = matrix.to_translation()
+             # pbone.rotation_quaternion = matrix.to_quaternion()
pbone.matrix_basis = matrix

pbone.keyframe_insert("location", -1, f, name)

pbone.keyframe_insert("scale", -1, f, name)

+     # object. TODO. multiple objects
+     if do_object:
+         if do_constraint_clear:
+             while obj.constraints:
+                 obj.constraints.remove(obj.constraints[0])
+         for f in frame_range:
+             matrix = obj_info[(f - frame_start) // step]["matrix_key"]
+             obj.matrix_local = matrix
+             obj.keyframe_insert("location", -1, f)
+             rotation_mode = obj.rotation_mode
+             if rotation_mode == 'QUATERNION':
+                 obj.keyframe_insert("rotation_quaternion", -1, f)
+             elif rotation_mode == 'AXIS_ANGLE':
+                 obj.keyframe_insert("rotation_axis_angle", -1, f)
+             else:  # euler, XYZ, ZXY etc
+                 obj.keyframe_insert("rotation_euler", -1, f)
+             obj.keyframe_insert("scale", -1, f)
+     scene.frame_set(frame_back)
return action

- from bpy.props import IntProperty, BoolProperty
+ from bpy.props import IntProperty, BoolProperty, EnumProperty

class BakeAction(bpy.types.Operator):
default=1, min=1, max=120)
only_selected = BoolProperty(name="Only Selected",
default=True)
+     clear_consraints = BoolProperty(name="Clear Constraints",
+             default=False)
+     bake_types = EnumProperty(
+             name="Bake Data",
+             options={'ENUM_FLAG'},
+             items=(('POSE', "Pose", ""),
+                    ('OBJECT', "Object", ""),
+                    ),
+             default={'POSE'},
+             )

def execute(self, context):

-         action = bake(self.frame_start, self.frame_end, self.step, self.only_selected)
+         action = bake(self.frame_start,
+                       self.frame_end,
+                       self.step,
+                       self.only_selected,
+                       'POSE' in self.bake_types,
+                       'OBJECT' in self.bake_types,
+                       self.clear_consraints,
+                       )
+         if action is None:
+             self.report({'INFO'}, "Nothing to bake")
+             return {'CANCELLED'}

# basic cleanup, could move elsewhere
for fcu in action.fcurves:
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
+
+#################################
+
+class ClearUselessActions(bpy.types.Operator):
+    '''Mark actions with no F-Curves for deletion after save+reload of file preserving "action libraries"'''
+    bl_idname = "anim.clear_useless_actions"
+    bl_label = "Clear Useless Actions"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    only_unused = BoolProperty(name="Only Unused",
+            description="Only unused (Fake User only) actions get considered",
+            default=True)
+
+    @classmethod
+    def poll(cls, context):
+        return len(bpy.data.actions) != 0
+
+    def execute(self, context):
+        removed = 0
+
+        for action in bpy.data.actions:
+            # if only user is "fake" user...
+            if ((self.only_unused is False) or
+                (action.use_fake_user and action.users == 1)):
+
+                # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
+                # and should be left alone as that's what fake users are for!
+                if not action.fcurves:
+                    # mark action for deletion
+                    action.user_clear()
+                    removed += 1
+
+        self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions" % (removed))
+        return {'FINISHED'}
@@@ -438,6 -438,8 +438,8 @@@ class USERPREF_PT_system(bpy.types.Pane
col.label(text="OpenGL:")
col.prop(system, "gl_clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
+         col.label(text="Anisotropic Filtering")
+         col.prop(system, "anisotropic_filter", text="")
col.prop(system, "use_vertex_buffer_objects")
#Anti-aliasing is disabled as it breaks broder/lasso select
#col.prop(system, "use_antialiasing")
@@@ -743,7 -745,6 +745,7 @@@ class USERPREF_PT_file(bpy.types.Panel)

col.prop(paths, "save_version")
col.prop(paths, "recent_files")
col.prop(paths, "use_save_preview_images")
col.label(text="Auto Save:")
col.prop(paths, "use_auto_save_temporary_files")
row.prop(toolsettings, "use_snap_peel_object", text="")
elif toolsettings.snap_element == 'FACE':
row.prop(toolsettings, "use_snap_project", text="")
+             if toolsettings.use_snap_project and obj.mode == 'EDIT':
+                 row.prop(toolsettings, "use_snap_project_self", text="")

# OpenGL render
row = layout.row(align=True)
@@@ -181,10 -183,6 +183,10 @@@ class VIEW3D_MT_transform(bpy.types.Men

layout.operator("object.randomize_transform")
layout.operator("object.align")
+
+        layout.separator()
+
+        layout.operator("object.anim_transforms_to_deltas")

@@@ -85,6 -85,8 +85,6 @@@ bAction *add_empty_action(const char na
bAction *act;

act= alloc_libblock(&G.main->action, ID_AC, name);
-      act->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
-      act->id.us++;

return act;
}
@@@ -198,6 -200,9 +198,6 @@@ bAction *copy_action (bAction *src
}
}

-      dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
-      dst->id.us++;
-
return dst;
}

@@@ -1123,7 -1128,7 +1123,7 @@@ void copy_pose_result(bPose *to, bPose
/* For the calculation of the effects of an Action at the given frame on an object
* This is currently only used for the Action Constraint
*/
- void what_does_obaction (Scene *UNUSED(scene), Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
+ void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
{
bActionGroup *agrp= action_groups_find_named(act, groupname);

@@@ -424,7 -424,7 +424,7 @@@ void constraint_mat_convertspace (Objec
/* ------------ General Target Matrix Tools ---------- */

/* function that sets the given matrix based on given vertex group in mesh */
- static void contarget_get_mesh_mat (Scene *scene, Object *ob, const char *substring, float mat[][4])
+ static void contarget_get_mesh_mat (Object *ob, const char *substring, float mat[][4])
{
DerivedMesh *dm = NULL;
Mesh *me= ob->data;
freeDM= 1;
}
else {
-               /* when not in EditMode, use the 'final' derived mesh
-                *      - check if the custom data masks for derivedFinal mean that we can just use that
-                *        (this is more effficient + sufficient for most cases)
-                */
-                       dm = mesh_get_derived_final(scene, ob, CD_MASK_MDEFORMVERT);
-                       freeDM= 1;
-               }
-               else
-                       dm = (DerivedMesh *)ob->derivedFinal;
+               /* when not in EditMode, use the 'final' derived mesh, depsgraph
+                * ensures we build with CD_MDEFORMVERT layer */
+               dm = (DerivedMesh *)ob->derivedFinal;
}

/* only continue if there's a valid DerivedMesh */
@@@ -587,7 -580,7 +580,7 @@@ static void contarget_get_lattice_mat (

/* generic function to get the appropriate matrix for most target cases */
/* The cases where the target can be object data have not been implemented */
- static void constraint_target_to_mat4 (Scene *scene, Object *ob, const char *substring, float mat[][4], short from, short to, float headtail)
+ static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], short from, short to, float headtail)
{
/*      Case OBJECT */
if (!strlen(substring)) {
*              way as constraints can only really affect things on object/bone level.
*/
else if (ob->type == OB_MESH) {
-               contarget_get_mesh_mat(scene, ob, substring, mat);
+               contarget_get_mesh_mat(ob, substring, mat);
constraint_mat_convertspace(ob, NULL, mat, from, to);
}
else if (ob->type == OB_LATTICE) {
@@@ -684,10 -677,10 +677,10 @@@ static bConstraintTypeInfo CTI_CONSTRNA
/* This function should be used for the get_target_matrix member of all
* constraints that are not picky about what happens to their target matrix.
*/
- static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+ static void default_get_tarmat (bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
{
if (VALID_CONS_TARGET(ct))
-               constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct)
unit_m4(ct->matrix);
}
@@@ -1159,7 -1152,7 +1152,7 @@@ static void kinematic_get_tarmat (bCons
bKinematicConstraint *data= con->data;

if (VALID_CONS_TARGET(ct))
-               constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct) {
if (data->flag & CONSTRAINT_IK_AUTO) {
Object *ob= cob->ob;
@@@ -2046,7 -2039,7 +2039,7 @@@ static void pycon_get_tarmat (bConstrai
/* firstly calculate the matrix the normal way, then let the py-function override
* this matrix if it needs to do so
*/
-               constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);

/* only execute target calculation if allowed */
#ifdef WITH_PYTHON
@@@ -2165,7 -2158,7 +2158,7 @@@ static void actcon_get_tarmat (bConstra
unit_m4(ct->matrix);

/* get the transform matrix of the target */
-               constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);

/* determine where in transform range target is */
/* data->type is mapped as follows for backwards compatability:
tchan->rotmode= pchan->rotmode;

/* evaluate action using workob (it will only set the PoseChannel in question) */
-                       what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, pchan->name, t);
+                       what_does_obaction(cob->ob, &workob, pose, data->act, pchan->name, t);

/* convert animation to matrices for use here */
pchan_calc_mat(tchan);

/* evaluate using workob */
// FIXME: we don't have any consistent standards on limiting effects on object...
-                       what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, NULL, t);
+                       what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
object_to_mat4(&workob, ct->matrix);
}
else {
@@@ -2648,7 -2641,7 +2641,7 @@@ static void distlimit_evaluate (bConstr
/* if inside, then move to surface */
if (dist <= data->dist) {
clamp_surf= 1;
-                              sfac= data->dist / dist;
+                              if (dist != 0.0f) sfac= data->dist / dist;
}
/* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
else if (data->flag & LIMITDIST_USESOFT) {
/* if outside, then move to surface */
if (dist >= data->dist) {
clamp_surf= 1;
-                              sfac= data->dist / dist;
+                              if (dist != 0.0f) sfac= data->dist / dist;
}
/* if soft-distance is enabled, start fading once owner is dist-soft from the target */
else if (data->flag & LIMITDIST_USESOFT) {
// FIXME: there's a problem with "jumping" when this kicks in
if (dist >= (data->dist - data->soft)) {
sfac = (float)( data->soft*(1.0f - expf(-(dist - data->dist)/data->soft)) + data->dist );
-                                      sfac /= dist;
+                                      if (dist != 0.0f) sfac /= dist;

clamp_surf= 1;
}
else {
if (IS_EQF(dist, data->dist)==0) {
clamp_surf= 1;
-                              sfac= data->dist / dist;
+                              if (dist != 0.0f) sfac= data->dist / dist;
}
}

@@@ -4427,34 -4420,6 +4420,34 @@@ void get_constraint_target_matrix (stru
unit_m4(mat);
}
}
+
+/* Get the list of targets required for solving a constraint */
+void get_constraint_targets_for_solving (bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+{
+      bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+      if (cti && cti->get_constraint_targets) {
+              bConstraintTarget *ct;
+
+              /* get targets
+               *      - constraints should use ct->matrix, not directly accessing values
+               *      - ct->matrix members have not yet been calculated here!
+               */
+              cti->get_constraint_targets(con, targets);
+
+              /* set matrices
+               *      - calculate if possible, otherwise just initialise as identity matrix
+               */
+              if (cti->get_target_matrix) {
+                      for (ct= targets->first; ct; ct= ct->next)
+                              cti->get_target_matrix(con, cob, ct, ctime);
+              }
+              else {
+                      for (ct= targets->first; ct; ct= ct->next)
+                              unit_m4(ct->matrix);
+              }
+      }
+}

/* ---------- Evaluation ----------- */

@@@ -4499,7 -4464,27 +4492,7 @@@ void solve_constraints (ListBase *conli
constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);

/* prepare targets for constraint solving */
-              if (cti->get_constraint_targets) {
-                      bConstraintTarget *ct;
-
-                      /* get targets
-                       *      - constraints should use ct->matrix, not directly accessing values
-                       *      - ct->matrix members have not yet been calculated here!
-                       */
-                      cti->get_constraint_targets(con, &targets);
-
-                      /* set matrices
-                       *      - calculate if possible, otherwise just initialise as identity matrix
-                       */
-                      if (cti->get_target_matrix) {
-                              for (ct= targets.first; ct; ct= ct->next)
-                                      cti->get_target_matrix(con, cob, ct, ctime);
-                      }
-                      else {
-                              for (ct= targets.first; ct; ct= ct->next)
-                                      unit_m4(ct->matrix);
-                      }
-              }
+              get_constraint_targets_for_solving(con, cob, &targets, ctime);

/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
@@@ -4321,6 -4321,7 +4321,7 @@@ static void direct_link_object(FileDat
MEM_freeN(hook);
}

ob->bb= NULL;
ob->derivedDeform= NULL;
ob->derivedFinal= NULL;
static void do_versions(FileData *fd, L
}
}
}
+
+              {
+                      /* convert fcurve actuator to action actuator */
+                      Object *ob;
+                      bActuator *act;
+                      bIpoActuator *ia;
+                      bActionActuator *aa;
+
+                      for (ob= main->object.first; ob; ob= ob->id.next) {
+                              for (act= ob->actuators.first; act; act= act->next) {
+                                      if (act->type == ACT_IPO) {
+                                              // Create the new actuator
+                                              ia= act->data;
+                                              aa= MEM_callocN(sizeof(bActionActuator), "fcurve -> action actuator do_version");
+
+                                              // Copy values
+                                              aa->type = ia->type;
+                                              aa->flag = ia->flag;
+                                              aa->sta = ia->sta;
+                                              aa->end = ia->end;
+                                              strcpy(aa->name, ia->name);
+                                              strcpy(aa->frameProp, ia->frameProp);
+
+                                              // Get rid of the old actuator
+                                              MEM_freeN(ia);
+
+                                              // Assign the new actuator
+                                              act->data = aa;
+                                              act->type= act->otype= ACT_ACTION;
+
+                                      }
+                              }
+                      }
+              }
}
-
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */

#include <algorithm>

- // use this for retrieving bone names, since these must be unique
+ // first try node name, if not available (since is optional), fall back to original id
template<class T>
static const char *bc_get_joint_name(T *node)
{
-       const std::string& id = node->getOriginalId();
-       return id.size() ? id.c_str() : node->getName().c_str();
+       const std::string& id = node->getName();
+       return id.size() ? id.c_str() : node->getOriginalId().c_str();
}

FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path)
@@@ -89,15 -89,12 +89,15 @@@ void AnimationImporter::animation_to_fc
{
-      // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
-      // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
+
+      if( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ) {
+      }
float fps = (float)FPS;
size_t dim = curve->getOutDimension();
unsigned int i;
-
+
std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];

switch (dim) {
fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
// fcu->rna_path = BLI_strdupn(path, strlen(path));
fcu->array_index = 0;
-                              //fcu->totvert = curve->getKeyCount();
+                              fcu->totvert = curve->getKeyCount();

// create beztriple for each key
for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));

-                                      // intangent
-                                      // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
-                                      // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
-
+
// input, output
bez.vec[1][0] = bc_get_float_value(input, j) * fps;
bez.vec[1][1] = bc_get_float_value(output, j * dim + i);

-                                      // outtangent
-                                      // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
-                                      // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);

-                                      bez.ipo = U.ipo_new; /* use default interpolation mode here... */
+                                      if( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER )
+                                      {
+
+                                              // intangent
+                                               bez.vec[0][0] = bc_get_float_value(intan, (j * 2 * dim ) + (2 * i)) * fps;
+                                               bez.vec[0][1] = bc_get_float_value(intan, (j * 2 * dim )+ (2 * i) + 1);
+
+                                               // outtangent
+                                               bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim ) + (2 * i)) * fps;
+                                               bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim )+ (2 * i) + 1);
+                                           bez.ipo = BEZT_IPO_BEZ;
+                                               //bez.h1 = bez.h2 = HD_AUTO;
+                                      }
+                                      else
+                                      {
+                                              bez.h1 = bez.h2 = HD_AUTO;
+                                              bez.ipo = BEZT_IPO_LIN;
+                                      }
+                                      // bez.ipo = U.ipo_new; /* use default interpolation mode here... */
bez.f1 = bez.f2 = bez.f3 = SELECT;
-                                      bez.h1 = bez.h2 = HD_AUTO;
+
insert_bezt_fcurve(fcu, &bez, 0);
}

unused_curves.push_back(*it);
}

+
{
for (unsigned int i = 0; i < cu->totvert; i++) {
// TODO convert handles too
cu->bezt[i].vec[1][1] *= M_PI / 180.0f;
+              cu->bezt[i].vec[0][1] *= M_PI / 180.0f;
+              cu->bezt[i].vec[2][1] *= M_PI / 180.0f;
+              cu->bezt[i].vec[1][0];
}
}

@@@ -298,11 -277,10 +298,11 @@@ bool AnimationImporter::write_animation
{
-
+
animlist_map[animlist_id] = animlist;
-
+
#if 0
+
// should not happen
if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
return true;
// what does this AnimationList animate?
Animation& animated = uid_animated_map[animlist_id];
Object *ob = animated.ob;
-
+
char rna_path[100];
char joint_path[100];
bool is_joint = false;

// if ob is NULL, it should be a JOINT
if (!ob) {
+
ob = armature_importer->get_armature_for_joint(animated.node);

if (!ob) {
-                      fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
+//                    fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
return true;
}

is_joint = true;
}
-
+      printf("object for animlist: %s found\n", animlist->getUniqueId().toAscii().c_str());

switch (animated.tm->getTransformationType()) {
@@@ -535,320 -512,66 +535,320 @@@ virtual void AnimationImporter::change_
}
#endif

-// prerequisites:
-// animlist_map - map animlist id -> animlist
-// curve_map - map anim id -> curve(s)
-                                                      Object *par_job)
+
+//sets the rna_path and array index to curve
+void AnimationImporter::modify_fcurve(std::vector<FCurve*>* curves , char* rna_path , int array_index )
+{
+      std::vector<FCurve*>::iterator it;
+      int i;
+      for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
+              FCurve *fcu = *it;
+              fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
+
+              if (array_index == -1) fcu->array_index = i;
+              else fcu->array_index = array_index;
+
+              unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
+      }
+}
+
+void AnimationImporter::find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves)
{
-      bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+      std::vector<FCurve*>::iterator iter;
+              for (iter = curves->begin(); iter != curves->end(); iter++) {
+                      FCurve *fcu = *iter;
+
+              for (unsigned int k = 0; k < fcu->totvert; k++) {
+                      //get frame value from bezTriple
+                      float fra = fcu->bezt[k].vec[1][0];
+                      if (std::find(frames->begin(), frames->end(), fra) == frames->end())
+                              frames->push_back(fra);
+
+              }
+              }
+}
+
+//creates the rna_paths and array indices of fcurves from animations using transformation and bound animation class of each animation.
+void AnimationImporter:: Assign_transform_animations(std::vector<float>* frames,
+                                                                                                       std::vector<FCurve*>* curves, bool is_joint, char * joint_path)
+{
bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
-      bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+      bool is_rotation = tm_type  == COLLADAFW::Transformation::ROTATE;
+
+      //to check if the no of curves are valid
+
+
+      if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
+              fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
+              return;
+      }
+
+      //find key frames of the animation and accumulates them to frames of the transformation.
+      find_frames (frames , curves );

+      char rna_path[100];
+      //char joint_path[100];
+
+
+      switch (tm_type) {
+                      {
+                              bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE;
+                              if (is_joint)
+                                      BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
+                              else
+                                      BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
+
+                              switch (binding->animationClass) {
+                                              modify_fcurve(curves, rna_path, 0 );
+                                              break;
+                                              modify_fcurve(curves, rna_path, 1 );
+                                              break;
+                                              modify_fcurve(curves, rna_path, 2 );
+                                              break;
+                                              modify_fcurve(curves, rna_path, -1 );
+                                              break;
+                                      default:
+                                              fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
+                                                              binding->animationClass, loc ? "TRANSLATE" : "SCALE");
+                                      }
+              break;
+                      }
+
+
+                      {
+                              if (is_joint)
+                                      BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
+                              else
+                                      BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
+                std::vector<FCurve*>::iterator iter;
+                              for (iter = curves->begin(); iter != curves->end(); iter++) {
+                                      FCurve* fcu = *iter;
+
+                                      //if transform is rotation the fcurves values must be turned in to radian.
+                                      if (is_rotation)
+                              }
+
+                              switch (binding->animationClass) {
+                                              if (COLLADABU::Math::Vector3::UNIT_X == axis) {
+                                                      modify_fcurve(curves, rna_path, 0 );
+                                              }
+                                              else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
+                                                      modify_fcurve(curves, rna_path, 1 );
+                                              }
+                                              else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
+                                                      modify_fcurve(curves, rna_path, 2 );
+                                              }
+                                              break;
+                                              // TODO convert axis-angle to quat? or XYZ?
+                                      default:
+                                              fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
+                                                              binding->animationClass);
+                                      }
+                      break;
+                      }
+
+                      fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n");
+                      break;
+              }
+
+}
+
+void AnimationImporter::translate_Animations_NEW ( COLLADAFW::Node * node ,
+{
+      bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+
COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
-      Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
+      Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map[node->getUniqueId()];
+
const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
+
+      if ( ! is_object_animated(node) ) return ;

+    char joint_path[200];
+
+      if ( is_joint )
+      armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
+
+      bAction * act;
+      bActionGroup *grp = NULL;
+
+                              //Get the list of animation curves of the object
+
+      ListBase *AnimCurves = &(act->curves);
+
if (!ob) {
fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
-              return NULL;
+              return;
}

-      // frames at which to sample
-      std::vector<float> frames;
+
+      /*float irest_dae[4][4];
+      float rest[4][4], irest[4][4];
+
+      if (is_joint) {
+              get_joint_rest_mat(irest_dae, root, node);
+              invert_m4(irest_dae);
+
+              Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
+              if (!bone) {
+                      fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
+                      return;
+              }
+
+              unit_m4(rest);
+              copy_m4_m4(rest, bone->arm_mat);
+              invert_m4_m4(irest, rest);
+      }*/
+
+      const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
+
+      //for each transformation in node
+      for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+
+              bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+              bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+
+              const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+
+              //might not be needed
+              std::vector<float> frames;
+
+              //check if transformation has animations
+              if (animlist_map.find(listid) == animlist_map.end()) continue ;
+              else
+                      {
+                              //transformation 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];
+                                      //calculate rnapaths and array index of fcurves according to transformation and animation class
+                                       Assign_transform_animations(&frames,transform, &bindings[j], &animcurves, is_joint, joint_path );
+
+                                       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;
+                                                       if (ob->type == OB_ARMATURE)
+                                                              add_bone_fcurve( ob, node , fcu );
+                                                       else
+                                              }
+                              }
+                       std::sort(frames.begin(), frames.end());
+                      }
+              if (is_rotation || is_matrix) {
+                      if (is_joint)
+                      {
+                              bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
+                              chan->rotmode = ROT_MODE_EUL;
+                      }
+                      else
+                      {
+                              ob->rotmode = ROT_MODE_EUL;
+                      }
+              }
+      }
+
+}
+
+//Check if object is animated by checking if animlist_map holds the animlist_id of node transforms
+bool AnimationImporter::is_object_animated ( const COLLADAFW::Node * node )
+{
+      bool exists = false;
+      const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
+
+      //for each transformation in node
+      for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+              const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+
+              //check if transformation has animations
+              if (animlist_map.find(listid) == animlist_map.end()) continue ;
+              else
+              {
+                      exists = true;
+                      break;
+              }
+      }
+
+      return exists;
+}

+//XXX Is not used anymore.
+{
+      bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+      bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
// for each <rotate>, <translate>, etc. there is a separate Transformation
-      const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
+      const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();

unsigned int i;
-
// find frames at which to sample plus convert all rotation keys to radians
-      for (i = 0; i < tms.getCount(); i++) {
+      for (i = 0; i < nodeTransforms.getCount(); i++) {

-              if (type == tm_type) {
-                      const COLLADAFW::UniqueId& listid = tm->getAnimationList();

+              if (nodeTmType == tm_type) {
+                      //get animation bindings for the current transformation
+                      const COLLADAFW::UniqueId& listid = transform->getAnimationList();
+                      //if transform is animated its animlist must exist.
if (animlist_map.find(listid) != animlist_map.end()) {
+
-
+
if (bindings.getCount()) {
+                                      //for each AnimationBinding get the fcurves which animate the transform
for (unsigned int j = 0; j < bindings.getCount(); j++) {
std::vector<FCurve*>& curves = curve_map[bindings[j].animation];

if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
std::vector<FCurve*>::iterator iter;

for (iter = curves.begin(); iter != curves.end(); iter++) {
FCurve *fcu = *iter;
-
+
+                                                              //if transform is rotation the fcurves values must be turned in to radian.
if (is_rotation)

for (unsigned int k = 0; k < fcu->totvert; k++) {
+                                                                      //get frame value from bezTriple
float fra = fcu->bezt[k].vec[1][0];
-                                                                      if (std::find(frames.begin(), frames.end(), fra) == frames.end())
-                                                                              frames.push_back(fra);
+                                                                      if (std::find(frames->begin(), frames->end(), fra) == frames->end())
+                                                                              frames->push_back(fra);
}
}
}
}
}
}
+}
+

+// prerequisites:
+// animlist_map - map animlist id -> animlist
+// curve_map - map anim id -> curve(s)
+                                                      Object *par_job)
+{
+
+      bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+      bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
+      bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+
+      COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
+      Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
+      const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
+      if (!ob) {
+              fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
+              return NULL;
+      }
+
+      // frames at which to sample
+      std::vector<float> frames;
+
+      find_frames_old(&frames, node , tm_type);
+
+      unsigned int i;
+
float irest_dae[4][4];
float rest[4][4], irest[4][4];

BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
else
strcpy(rna_path, tm_str);
-
newcu[i] = create_fcurve(axis, rna_path);

#ifdef ARMATURE_TEST
@@@ -1134,7 -827,8 +1134,8 @@@ void AnimationImporter::evaluate_transf

unit_m4(m);

-               if (!evaluate_animation(tm, m, fra, node->getOriginalId().c_str())) {
+               std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
+               if (!evaluate_animation(tm, m, fra, nodename.c_str())) {
switch (type) {
dae_rotate_to_mat4(tm, m);

#include "ArmatureImporter.h"

- // use this for retrieving bone names, since these must be unique
+ // use node name, or fall back to original id if not present (name is optional)
template<class T>
static const char *bc_get_joint_name(T *node)
{
-       const std::string& id = node->getOriginalId();
-       return id.size() ? id.c_str() : node->getName().c_str();
+       const std::string& id = node->getName();
+       return id.size() ? id.c_str() : node->getOriginalId().c_str();
}

ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
@@@ -78,67 -78,6 +78,67 @@@ JointData *ArmatureImporter::get_joint_
return &joint_index_to_joint_info_map[joint_index];
}
#endif
+void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *parent, int totchild,
+                               float parent_mat[][4], bArmature *arm)
+{
+      float mat[4][4];
+   float obmat[4][4];
+
+      // object-space
+      get_node_mat(obmat, node, NULL, NULL);
+
+      // get world-space
+      if (parent)
+              mul_m4_m4m4(mat, obmat, parent_mat);
+      else
+              copy_m4_m4(mat, obmat);
+
+      EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node));
+      totbone++;
+
+      if (parent) bone->parent = parent;
+
+
+      // set tail, don't set it to head because 0-length bones are not allowed
+      float vec[3] = {0.0f, 0.5f, 0.0f};
+
+      // set parent tail
+      if (parent && totchild == 1) {
+
+              // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
+              // bone->flag |= BONE_CONNECTED;
+
+              // XXX increase this to prevent "very" small bones?
+              const float epsilon = 0.000001f;
+
+              // derive leaf bone length
+              float length = len_v3v3(parent->head, parent->tail);
+              if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
+                      leaf_bone_length = length;
+              }
+
+              // treat zero-sized bone like a leaf bone
+              if (length <= epsilon) {
+              }
+
+      }
+
+      for (unsigned int i = 0; i < children.getCount(); i++) {
+              create_unskinned_bone( children[i], bone, children.getCount(), mat, arm);
+      }
+
+      // in second case it's not a leaf bone, but we handle it the same way
+      if (!children.getCount() || children.getCount() > 1) {
+      }
+
+}

void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[][4], bArmature *arm)
@@@ -361,47 -300,6 +361,47 @@@ ArmatureJoints& ArmatureImporter::get_a
return armature_joints.back();
}
#endif
+void ArmatureImporter::create_armature_bones( )
+{
+      //if there is an armature created for root_joint next root_joint
+      for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
+                      if ( get_armature_for_joint(*ri) != NULL ) continue;
+
+        //add armature object for current joint
+              //Object *ob_arm = add_object(scene, OB_ARMATURE);
+
+              Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
+              //ob_arm->type = OB_ARMATURE;
+              ED_armature_to_edit(ob_arm);
+
+              // min_angle = 360.0f;          // minimum angle between bone head-tail and a row of bone matrix
+
+              // create unskinned bones
+              /*
+                 TODO:
+                 check if bones have already been created for a given joint
+              */
+     leaf_bone_length = FLT_MAX;
+              create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
+
+              fix_leaf_bones();
+
+      // exit armature edit mode
+
+
+      //if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && ob_arm->parent!=NULL)
+      //      ob_arm->parent = joint_parent_map[(*ri)->getUniqueId()];
+
+      unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
+
+      ED_armature_from_edit(ob_arm);
+      ED_armature_edit_free(ob_arm);
+      DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
+      }
+
+
+}

void ArmatureImporter::create_armature_bones(SkinInfo& skin)
{
if (shared)
ob_arm = skin.set_armature(shared);
else
-              ob_arm = skin.create_armature(scene);
+              ob_arm = skin.create_armature(scene); //once for every armature

// enter armature edit mode
ED_armature_to_edit(ob_arm);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);

// set_leaf_bone_shapes(ob_arm);
-      // set_euler_rotmode();
+    // set_euler_rotmode();
}

// root - if this joint is the top joint in hierarchy, if a joint
// is a child of a node (not joint), root should be true since
// this is where we build armature bones from
+
{
joint_by_uid[node->getUniqueId()] = node;
if (root) {
root_joints.push_back(node);

-              if (parent)
+              if (parent) {
+
joint_parent_map[node->getUniqueId()] = parent;
+              }
}
}

@@@ -577,9 -472,6 +577,9 @@@ void ArmatureImporter::make_armatures(b
// free memory stolen from SkinControllerData
skin.free();
}
+
+      create_armature_bones();
+
}

#if 0
@@@ -674,12 -566,7 +674,12 @@@ Object *ArmatureImporter::get_armature_
if (skin.uses_joint_or_descendant(node))
return skin.get_armature();
}
-
+
+      for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) {
+              if(arm->first == node->getUniqueId() )
+                      return arm->second;
+      }
return NULL;
}

@@@ -44,25 -44,24 +44,25 @@@ set(INC_SY

if(APPLE)
list(APPEND INC_SYS
)
else()
list(APPEND INC_SYS
)
endif()

set(SRC
AnimationImporter.cpp
+      AnimationExporter.cpp
ArmatureExporter.cpp
ArmatureImporter.cpp
CameraExporter.cpp
@@@ -85,7 -84,6 +85,7 @@@

AnimationImporter.h
+      AnimationExporter.h
ArmatureExporter.h
ArmatureImporter.h
CameraExporter.h
@@@ -250,13 -250,12 +250,13 @@@ void DocumentImporter::translate_anim_r
unsigned int i;
Object *ob;

-      for (i = 0; i < 4; i++)
-              ob = anim_importer.translate_animation(node, object_map, root_map, types[i]);
+      //for (i = 0; i < 4; i++)
+              //ob =
+      anim_importer.translate_Animations_NEW(node, root_map, object_map);

for (i = 0; i < children.getCount(); i++) {
-              translate_anim_recursive(children[i], node, ob);
+              translate_anim_recursive(children[i], node, NULL);
}
}

@@@ -310,7 -309,7 +310,7 @@@ Object* DocumentImporter::create_lamp_o
return ob;
}

- Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node)
+ Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, Object *par_ob, bool is_library_node)
{
Object *obn = copy_object(source_ob);
obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
Object *new_child = NULL;
if (inodes.getCount()) { // \todo loop through instance nodes
-                               new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, is_library_node);
+                               new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, NULL, is_library_node);
}
else {
-                               new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, is_library_node);
+                               new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, NULL, is_library_node);
}
bc_set_parent(new_child, obn, mContext, true);

// when we have an instance_node, don't return the object, because otherwise
// its correct location gets overwritten in write_node(). Fixes bug #26012.
-       if(instance_node) return NULL;
+       if(instance_node) {
+               if (par_ob && obn)
+                       bc_set_parent(obn, par_ob, mContext);
+               return NULL;
+       }
else return obn;
}

@@@ -378,14 -382,7 +383,14 @@@ void DocumentImporter::write_node (COLL
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;

if (is_joint) {
+              if ( par ) {
+              Object * empty = par;
+              bc_set_parent(par,empty->parent, mContext);
+              //remove empty : todo
+              object_map[parent_node->getUniqueId()] = par;
+              }
}
else {
-               int geom_done = 0;
-               int camera_done = 0;
-               int lamp_done = 0;
-               int controller_done = 0;
-               int inst_done = 0;
+               size_t geom_done = 0;
+               size_t camera_done = 0;
+               size_t lamp_done = 0;
+               size_t controller_done = 0;
+               size_t inst_done = 0;

// XXX linking object with the first <instance_geometry>, though a node may have more of them...
// maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
Object *source_ob = object_map[node_id];

-                               ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
+                               ob = create_instance_node(source_ob, source_node, node, sce, par, is_library_node);
}
++inst_done;
}
// check if object is not NULL
if (!ob) return;

-               rename_id(&ob->id, (char*)node->getOriginalId().c_str());
+               std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
+               rename_id(&ob->id, (char*)nodename.c_str());

object_map[node->getUniqueId()] = ob;
node_map[node->getUniqueId()] = node;
@@@ -526,7 -524,7 +532,7 @@@ bool DocumentImporter::writeMaterial( c
if(mImportStage!=General)
return true;

-       const std::string& str_mat_id = cmat->getOriginalId();
+       const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();

this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
@@@ -678,6 -676,18 +684,18 @@@ void DocumentImporter::write_profile_CO
i++;
}
}
+
+       if(ef->getOpacity().isTexture()) {
+               mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
+               if(mtex != NULL) {
+                       mtex->mapto = MAP_ALPHA;
+                       mtex->tex->imaflag |= TEX_USEALPHA;
+                       i++;
+                       ma->spectra = ma->alpha = 0;
+                       ma->mode |= MA_ZTRANSP|MA_TRANSP;
+               }
+       }
// TRANSPARENT
// color
//    if (ef->getOpacity().isColor()) {
#include "SkinInfo.h"

- // use this for retrieving bone names, since these must be unique
+ // use name, or fall back to original id if name not present (name is optional)
template<class T>
static const char *bc_get_joint_name(T *node)
{
-       const std::string& id = node->getOriginalId();
-       return id.size() ? id.c_str() : node->getName().c_str();
+       const std::string& id = node->getName();
+       return id.size() ? id.c_str() : node->getOriginalId().c_str();
}

// This is used to store data passed in write_controller_data.
@@@ -308,15 -308,11 +308,15 @@@ void SkinInfo::find_root_joints(const s
{
+      // for each root_joint
for (it = root_joints.begin(); it != root_joints.end(); it++) {
std::vector<JointData>::iterator ji;
+              //for each joint_data in this skin
for (ji = joint_data.begin(); ji != joint_data.end(); ji++) {
+                      //get joint node from joint map
+                      //find if joint node is in the tree belonging to the root_joint
if (find_node_in_tree(joint, root)) {
if (std::find(result.begin(), result.end(), root) == result.end())
result.push_back(root);
@@@ -663,7 -663,7 +663,7 @@@ void ui_theme_init_default(void

SETCOL(btheme->tipo.handle_vertex,              0, 0, 0, 255);
SETCOL(btheme->tipo.handle_vertex_select, 255, 133, 0, 255);
-      btheme->tipo.handle_vertex_size= 3;
+      btheme->tipo.handle_vertex_size= 4;

SETCOL(btheme->tipo.ds_channel,         82, 96, 110, 255);
SETCOL(btheme->tipo.ds_subchannel,      124, 137, 150, 255);
@@@ -1580,6 -1580,8 +1580,8 @@@ void init_userdef_do_versions(void
U.dragthreshold= 5;
if (U.widget_unit==0)
U.widget_unit= (U.dpi * 20 + 36)/72;
+       if (U.anisotropic_filter <= 0)
+               U.anisotropic_filter = 1;

/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX        space_set_commmandline_options();
@@@ -1217,87 -1217,6 +1217,87 @@@ static void draw_b_bone(int dt, int arm
}
}

+static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments)
+{
+      if ((segments > 1) && (pchan)) {
+              float dlen= length/(float)segments;
+              Mat4 *bbone = bbones;
+              int a;
+
+              for (a=0; a<segments; a++, bbone++) {
+                      glPushMatrix();
+                      glMultMatrixf(bbone->mat);
+
+                      glBegin(GL_LINES);
+                      glVertex3f(0.0f, 0.0f, 0.0f);
+                      glVertex3f(0.0f, dlen, 0.0f);
+                      glEnd(); // GL_LINES
+
+                      glPopMatrix();
+              }
+      }
+      else {
+              glPushMatrix();
+
+              glBegin(GL_LINES);
+              glVertex3f(0.0f, 0.0f, 0.0f);
+              glVertex3f(0.0f, length, 0.0f);
+              glEnd();
+
+              glPopMatrix();
+      }
+}
+
+static void draw_wire_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
+{
+      Mat4 *bbones = NULL;
+      int segments = 0;
+      float length;
+
+      if (pchan) {
+              segments= pchan->bone->segments;
+              length= pchan->bone->length;
+
+              if (segments > 1)
+                      bbones = b_bone_spline_setup(pchan, 0);
+      }
+      else
+              length= ebone->length;
+
+      /* draw points only if... */
+      if (armflag & ARM_EDITMODE) {
+              /* move to unitspace */
+              glPushMatrix();
+              glScalef(length, length, length);
+              draw_bone_points(dt, armflag, boneflag, id);
+              glPopMatrix();
+              length *= 0.95f;        // make vertices visible
+      }
+
+      /* this chunk not in object mode */
+      if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
+              if (id != -1)
+
+              draw_wire_bone_segments(pchan, bbones, length, segments);
+
+              /* further we send no names */
+              if (id != -1)
+                      glLoadName(id & 0xFFFF);        /* object tag, for bordersel optim */
+      }
+
+      /* colors for modes */
+      if (armflag & ARM_POSEMODE) {
+              set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+      }
+      else if (armflag & ARM_EDITMODE) {
+              set_ebone_glColor(boneflag);
+      }
+
+      /* draw normal */
+      draw_wire_bone_segments(pchan, bbones, length, segments);
+}
+
static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length)
{

@@@ -1658,7 -1577,7 +1658,7 @@@ static void bone_matrix_translate_y(flo
}

/* assumes object is Armature with pose */
- static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, short ghost)
+ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, const short is_ghost, const short is_outline)
{
RegionView3D *rv3d= ar->regiondata;
Object *ob= base->object;
int use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
glPushMatrix();

-                                      if(use_custom && pchan->custom_tx) {
+                                      if (use_custom && pchan->custom_tx) {
glMultMatrixf(pchan->custom_tx->pose_mat);
}
else {
}
else if (arm->drawtype==ARM_LINE)
;       /* nothing in solid */
+                                      else if (arm->drawtype==ARM_WIRE)
+                                              ;       /* nothing in solid */
else if (arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
else if (arm->drawtype==ARM_B_BONE)
/* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet,
* stick bones and/or wire custom-shapes are drawn in next loop
*/
-              if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) {
+              if (ELEM(arm->drawtype,ARM_LINE,ARM_WIRE)==0 && (draw_wire == 0)) {
/* object tag, for bordersel optim */
index= -1;
}

/* prepare colors */
-                                                       if(ghost) {
+                                                       if(is_ghost) {
/* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */
}
else if (arm->flag & ARM_POSEMODE)
if (index != -1)
index+= 0x10000;        // pose bones count in higher 2 bytes only
}
-              /* stick bones have not been drawn yet so dont clear object selection in this case */
-              if ((arm->drawtype != ARM_LINE) && draw_wire) {
+              /* stick or wire bones have not been drawn yet so dont clear object selection in this case */
+              if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)==0 && draw_wire) {
/* object tag, for bordersel optim */
index= -1;
/* wire draw over solid only in posemode */
if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) {
/* draw line check first. we do selection indices */
-              if (arm->drawtype==ARM_LINE) {
+              if ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) {
if (arm->flag & ARM_POSEMODE)
index= base->selcol;
}
}
else if (arm->drawtype==ARM_LINE)
draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
+                                      else if (arm->drawtype==ARM_WIRE)
+                                              draw_wire_bone(dt, arm->flag, flag, constflag, index, pchan, NULL);
else if (arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
else
draw_pose_dofs(ob);

/* finally names and axes */
-       if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
+       if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES) && is_outline == 0) {
/* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
if ((G.f & G_PICKSEL) == 0) {
float vec[3];
@@@ -2098,7 -2013,7 +2098,7 @@@ static void draw_ebones(View3D *v3d, AR
}

/* if solid we draw it first */
-      if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) {
+      if ((dt > OB_WIRE) && (arm->drawtype != ARM_LINE)) {
for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A)==0) {
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
else if(arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
+                                      else if (arm->drawtype==ARM_WIRE)
+                                              draw_wire_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
else {
draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
}
/* if wire over solid, set offset */
index= -1;
-      if (arm->drawtype==ARM_LINE) {
+      if ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) {
if(G.f & G_PICKSEL)
index= 0;
}

if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
+                                      else if (arm->drawtype==ARM_WIRE)
+                                              draw_wire_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
else if (arm->drawtype == ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
else

/* restore */
-      if (arm->drawtype==ARM_LINE);
+      if ELEM(arm->drawtype,ARM_LINE,ARM_WIRE);
else if (dt>OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f);

/* finally names and axes */
@@@ -2348,7 -2259,7 +2348,7 @@@ static void draw_ghost_poses_range(Scen

where_is_pose(scene, ob);
-               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE);
+               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@@ -2427,7 -2338,7 +2427,7 @@@ static void draw_ghost_poses_keys(Scen

where_is_pose(scene, ob);
-               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE);
+               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@@ -2497,7 -2408,7 +2497,7 @@@ static void draw_ghost_poses(Scene *sce
if (CFRA != cfrao) {
where_is_pose(scene, ob);
-                               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE);
+                               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
}

if (CFRA != cfrao) {
where_is_pose(scene, ob);
-                               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE);
+                               draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
}
}
/* ********************************** Armature Drawing - Main ************************* */

/* called from drawobject.c, return 1 if nothing was drawn */
- int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag)
+ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline)
{
Object *ob= base->object;
bArmature *arm= ob->data;
}
}
}
-                       draw_pose_bones(scene, v3d, ar, base, dt, FALSE);
+                       draw_pose_bones(scene, v3d, ar, base, dt, FALSE, is_outline);
arm->flag &= ~ARM_POSEMODE;

if(ob->mode & OB_MODE_POSE)
@@@ -3131,18 -3131,12 +3131,18 @@@ static void createTransActionData(bCont
float min=999999999.0f, max=-999999999.0f;
int i;

-              td= (t->data + 1);
-              for (i=1; i < count; i+=3, td+=3) {
+              td= t->data;
+              for (i=0; i < count; i++, td++) {
if (min > *(td->val)) min= *(td->val);
if (max < *(td->val)) max= *(td->val);
}

+              if (min == max) {
+                      /* just use the current frame ranges */
+                      min = (float)PSFRA;
+                      max = (float)PEFRA;
+              }
+
/* minx/maxx values used by TimeSlide are stored as a
* calloced 2-float array in t->customData. This gets freed
* in postTrans (T_FREE_CUSTOMDATA).
@@@ -3731,27 -3725,8 +3731,8 @@@ void flushTransGraphData(TransInfo *t
* seq->depth must be set before running this function so we know if the strips
* are root level or not
*/
- #define XXX_DURIAN_ANIM_TX_HACK
static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count, int *flag)
{
-
- #ifdef XXX_DURIAN_ANIM_TX_HACK
-       /* hack */
-       if((seq->flag & SELECT)==0 && seq->type & SEQ_EFFECT) {
-               Sequence *seq_t[3];
-               int i;
-               seq_t[0]= seq->seq1;
-               seq_t[1]= seq->seq2;
-               seq_t[2]= seq->seq3;
-               for(i=0; i<3; i++) {
-                       if (seq_t[i] && ((seq_t[i])->flag & SELECT) && !(seq_t[i]->flag & SEQ_LOCK) && !(seq_t[i]->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)))
-                               seq->flag |= SELECT;
-               }
-       }
- #endif
/* for extend we need to do some tricks */
if (t->mode == TFM_TIME_EXTEND) {

@@@ -4111,6 -4086,7 +4092,7 @@@ static void freeSeqData(TransInfo *t

static void createTransSeqData(bContext *C, TransInfo *t)
{
+ #define XXX_DURIAN_ANIM_TX_HACK

View2D *v2d= UI_view2d_fromcontext(C);
Scene *scene= t->scene;
t->frame_side = 'B';
}

+ #ifdef XXX_DURIAN_ANIM_TX_HACK
+       {
+               Sequence *seq;
+               for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+                       /* hack */
+                       if((seq->flag & SELECT)==0 && seq->type & SEQ_EFFECT) {
+                               Sequence *seq_user;
+                               int i;
+                               for(i=0; i<3; i++) {
+                                       seq_user= *((&seq->seq1) + i);
+                                       if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) && !(seq_user->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL))) {
+                                               seq->flag |= SELECT;
+                                       }
+                               }
+                       }
+               }
+       }
+ #endif

count = SeqTransCount(t, ed->seqbasep, 0);

/* loop 2: build transdata array */
SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
+ #undef XXX_DURIAN_ANIM_TX_HACK
}

@@@ -5083,10 -5079,6 +5085,6 @@@ void special_aftertrans_update(bContex
#if 0 // TRANSFORM_FIX_ME
if(resetslowpar)
reset_slowparents();
-       /* note; should actually only be done for all objects when a lamp is moved... (ton) */
-       if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED)
#endif
}

@@@ -375,7 -375,7 +375,7 @@@ typedef struct UserDef
short scrcastwait;              /* milliseconds between screencast snapshots */

short widget_unit;              /* defaults to 20 for 72 DPI setting */
+       short anisotropic_filter;

char versemaster[160];
char verseuser[160];
short autokey_flag;             /* flags for autokeying */

short text_render, pad9;                /*options for text rendering*/

struct ColorBand coba_weight;   /* from texture.h */

@@@ -436,7 -435,6 +435,7 @@@ extern UserDef U; /* from blenkernel bl
#define USER_NONEGFRAMES              (1 << 24)
#define USER_TXT_TABSTOSPACES_DISABLE (1 << 25)
#define USER_TOOLTIPS_PYTHON    (1 << 26)

/* helper macro for checking frame clamping */
@@@ -534,7 -534,6 +534,7 @@@ extern StructRNA RNA_ThemeWidgetColors
extern StructRNA RNA_ThemeWidgetStateColors;
extern StructRNA RNA_TimelineMarker;
extern StructRNA RNA_Timer;
+extern StructRNA RNA_TitleCardSequence;
extern StructRNA RNA_ToolSettings;
extern StructRNA RNA_TouchSensor;
extern StructRNA RNA_TrackToConstraint;
@@@ -717,6 -716,7 +717,7 @@@ int RNA_property_boolean_get_default_in
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value);
void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values);
+ void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2]);
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index);
void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values);
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value);
@@@ -727,6 -727,7 +728,7 @@@ int RNA_property_int_get_default_index(
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value);
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values);
+ void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2]);
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index);
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values);
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value);
@@@ -1643,6 -1643,43 +1643,43 @@@ void RNA_property_int_get_array(Pointer
memset(values, 0, sizeof(int)*prop->totarraylength);
}

+ void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
+ {
+       const int array_len= RNA_property_array_length(ptr, prop);
+       if(array_len <= 0) {
+               values[0]= 0;
+               values[1]= 0;
+       }
+       else if (array_len == 1) {
+               RNA_property_int_get_array(ptr, prop, values);
+               values[1]= values[0];
+       }
+       else {
+               int arr_stack[32];
+               int *arr;
+               int i;
+               if(array_len > 32) {
+                       arr= MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
+               }
+               else {
+                       arr= arr_stack;
+               }
+               RNA_property_int_get_array(ptr, prop, arr);
+               values[0]= values[1]= arr[0];
+               for(i= 1; i < array_len; i++) {
+                       values[0]= MIN2(values[0], arr[i]);
+                       values[1]= MAX2(values[1], arr[i]);
+               }
+               if(arr != arr_stack) {
+                       MEM_freeN(arr);
+               }
+       }
+ }
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
{
int tmp[RNA_MAX_ARRAY_LENGTH];
@@@ -1839,6 -1876,43 +1876,43 @@@ void RNA_property_float_get_array(Point
memset(values, 0, sizeof(float)*prop->totarraylength);
}

+ void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
+ {
+       const int array_len= RNA_property_array_length(ptr, prop);
+       if(array_len <= 0) {
+               values[0]= 0.0f;
+               values[1]= 0.0f;
+       }
+       else if (array_len == 1) {
+               RNA_property_float_get_array(ptr, prop, values);
+               values[1]= values[0];
+       }
+       else {
+               float arr_stack[32];
+               float *arr;
+               int i;
+               if(array_len > 32) {
+                       arr= MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
+               }
+               else {
+                       arr= arr_stack;
+               }
+               RNA_property_float_get_array(ptr, prop, arr);
+               values[0]= values[1]= arr[0];
+               for(i= 1; i < array_len; i++) {
+                       values[0]= MIN2(values[0], arr[i]);
+                       values[1]= MAX2(values[1], arr[i]);
+               }
+               if(arr != arr_stack) {
+                       MEM_freeN(arr);
+               }
+       }
+ }
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
{
float tmp[RNA_MAX_ARRAY_LENGTH];
@@@ -3114,7 -3188,7 +3188,7 @@@ static char *rna_path_token(const char
/* 2 kinds of lookups now, quoted or unquoted */
quote= *p;

-              if(quote != '"')
+              if(quote != '"') /* " - this comment is hack for Aligorith's text editor's sanity */
quote= 0;

if(quote==0) {
@@@ -117,6 -117,12 +117,12 @@@ static void rna_userdef_mipmap_update(M
rna_userdef_update(bmain, scene, ptr);
}

+ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+ {
+       GPU_set_anisotropic(U.anisotropic_filter);
+       rna_userdef_update(bmain, scene, ptr);
+ }
static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
GPU_free_images();
@@@ -2109,19 -2115,22 +2115,22 @@@ static void rna_def_userdef_view(Blende
prop= RNA_def_property(srna, "manipulator_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tw_size");
RNA_def_property_range(prop, 2, 40);
+       RNA_def_property_int_default(prop, 15);
RNA_def_property_ui_text(prop, "Manipulator Size", "Diameter of widget, in 10 pixel units");
RNA_def_property_update(prop, 0, "rna_userdef_update");

prop= RNA_def_property(srna, "manipulator_handle_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tw_handlesize");
RNA_def_property_range(prop, 2, 40);
+       RNA_def_property_int_default(prop, 25);
RNA_def_property_ui_text(prop, "Manipulator Handle Size", "Size of widget handles as percentage of widget radius");
RNA_def_property_update(prop, 0, "rna_userdef_update");

prop= RNA_def_property(srna, "manipulator_hotspot", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tw_hotspot");
RNA_def_property_range(prop, 4, 40);
-       RNA_def_property_ui_text(prop, "Manipulator Hotspot", "Hotspot in pixels for clicking widget handles");
+       RNA_def_property_int_default(prop, 14);
+       RNA_def_property_ui_text(prop, "Manipulator Hotspot", "Pixel distance around the handles to accept mouse clicks");

prop= RNA_def_property(srna, "object_origin_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "obcenter_dia");
@@@ -2346,6 -2355,14 +2355,14 @@@ static void rna_def_userdef_system(Blen
{128, "CLAMP_128", 0, "128", ""},
{0, NULL, 0, NULL, NULL}};

+       static EnumPropertyItem anisotropic_items[]  ={
+               {1, "FILTER_0", 0, "Off", ""},
+               {2, "FILTER_2", 0, "2x", ""},
+               {4, "FILTER_4", 0, "4x", ""},
+               {8, "FILTER_8", 0, "8x", ""},
+               {16, "FILTER_16", 0, "16x", ""},
+               {0, NULL, 0, NULL, NULL}};
static EnumPropertyItem audio_mixing_samples_items[] = {
{256, "SAMPLES_256", 0, "256", "Set audio mixing buffer size to 256 samples"},
{512, "SAMPLES_512", 0, "512", "Set audio mixing buffer size to 512 samples"},
prop= RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_AA);
RNA_def_property_ui_text(prop, "Anti-aliasing", "Use anti-aliasing for the 3D view (may impact redraw performance)");
+       prop= RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "anisotropic_filter");
+       RNA_def_property_enum_items(prop, anisotropic_items);
+       RNA_def_property_enum_default(prop, 1);
+       RNA_def_property_ui_text(prop, "Anisotropic Filter", "The quality of the anisotropic filtering (values greater than 1.0 enable anisotropic filtering)");
+       RNA_def_property_update(prop, 0, "rna_userdef_anisotropic_update");

prop= RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "glreslimit");
@@@ -2878,11 -2902,7 +2902,11 @@@ static void rna_def_userdef_filepaths(B
prop= RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember");
-
+
+      prop= RNA_def_property(srna, "use_update_recent_files_on_load", PROP_BOOLEAN, PROP_NONE);
+      RNA_def_property_ui_text(prop, "Update Recent on Load", "When enabled, opening files will update the recent files list. Otherwise, updates only occur when saving");
+
prop= RNA_def_property(srna, "use_save_preview_images", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_SAVE_PREVIEWS);
RNA_def_property_ui_text(prop, "Save Preview Images", "Enables automatic saving of preview images in the .blend file");
@@@ -36,7 -36,6 +36,7 @@@
#include "BL_ActionActuator.h"
#include "BL_ArmatureObject.h"
#include "BL_SkinDeformer.h"
+#include "BL_Action.h"
#include "KX_GameObject.h"
#include "STR_HashedString.h"
#include "MEM_guardedalloc.h"
@@@ -144,90 -143,7 +144,90 @@@ void BL_ActionActuator::SetLocalTime(fl
m_localtime = m_endframe - delta_time;
}

+bool BL_ActionActuator::Update(double curtime, bool frame)
+{
+      bool bNegativeEvent = false;
+      bool bPositiveEvent = false;
+      KX_GameObject *obj = (KX_GameObject*)GetParent();
+      short play_mode = BL_Action::ACT_MODE_PLAY;
+      float start = m_startframe, end = m_endframe;
+
+      // If we don't have an action, we can't do anything
+      if (!m_action)
+              return false;
+
+      // Don't do anything if we're not "active"
+      if (!frame)
+              return true;
+
+      // Convert playmode
+      if (m_playtype == ACT_ACTION_LOOP_END)
+              play_mode = BL_Action::ACT_MODE_LOOP;
+      else if (m_playtype == ACT_ACTION_LOOP_STOP)
+              play_mode = BL_Action::ACT_MODE_LOOP;
+      else if (m_playtype == ACT_ACTION_PINGPONG)
+              play_mode = BL_Action::ACT_MODE_PING_PONG;
+      else if (m_playtype == ACT_ACTION_FROM_PROP)
+      {
+              CValue* prop = GetParent()->GetProperty(m_propname);
+
+              play_mode = BL_Action::ACT_MODE_PLAY;
+              start = end = prop->GetNumber();
+              m_is_going = false;
+      }
+
+      // Handle events
+      bNegativeEvent = m_negevent;
+      bPositiveEvent = m_posevent;
+      RemoveAllEvents();
+
+      if (!m_is_going && bPositiveEvent)
+      {
+              m_is_going = true;
+              obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_blendin, play_mode, 0, m_ipo_flags);
+              if (m_end_reset)
+                      obj->SetActionFrame(m_layer, m_localtime);
+      }
+      else if (m_is_going && bNegativeEvent)
+      {
+              m_is_going = false;
+
+              if (!m_end_reset)
+              {
+                      obj->StopAction(m_layer);
+                      return false;
+              }
+
+              m_localtime = obj->GetActionFrame(m_layer);
+              obj->StopAction(m_layer); // Stop the action after getting the frame
+      }
+
+      // Handle a frame property if it's defined
+      if (m_framepropname[0] != 0)
+      {
+              CValue* oldprop = obj->GetProperty(m_framepropname);
+              CValue* newval = new CFloatValue(obj->GetActionFrame(m_layer));
+              if (oldprop)
+                      oldprop->SetValue(newval);
+              else
+                      obj->SetProperty(m_framepropname, newval);
+
+              newval->Release();
+      }
+      if (m_playtype == ACT_ACTION_FROM_PROP)
+      {
+              return true;
+      }
+      // Handle a finished animation
+      else if (m_is_going && obj->IsActionDone(m_layer))
+      {
+              return false;
+      }
+
+      return true;
+}

+#if 0 // Kept around as reference for now
bool BL_ActionActuator::Update(double curtime, bool frame)
{
bool bNegativeEvent = false;

// 2.5x - could also do this but looks too high level, constraints use this, it works ok.
//                            Object workob; /* evaluate using workob */
- //                            what_does_obaction((Scene *)obj->GetScene(), obj->GetArmatureObject(), &workob, m_pose, m_action, NULL, m_localtime);
+ //                            what_does_obaction(obj->GetArmatureObject(), &workob, m_pose, m_action, NULL, m_localtime);
}

// done getting the pose from the action
}
return keepgoing;
};
+#endif

#ifdef WITH_PYTHON