Corrections to alpha pipeline do_versions
[blender.git] / source / blender / blenloader / intern / readfile.c
index a67c0b8..93bc050 100644 (file)
@@ -81,6 +81,7 @@
 #include "DNA_packedFile_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
 #include "DNA_text_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_screen_types.h"
  * - initialize FileGlobal and copy pointers to Global
  */
 
-/* also occurs in library.c */
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a)  (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x  */
-/*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
 /***/
 
 typedef struct OldNew {
@@ -1864,8 +1851,8 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
                        if (prv->rect[i]) {
                                prv->rect[i] = newdataadr(fd, prv->rect[i]);
                        }
+                       prv->gputexture[i] = NULL;
                }
-//             prv->gputexture[0] = prv->gputexture[1] = NULL;
        }
        
        return prv;
@@ -2692,15 +2679,15 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
                                data->prop = newdataadr(fd, data->prop);
                                if (data->prop)
                                        IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-                       }
                                break;
+                       }
                        case CONSTRAINT_TYPE_SPLINEIK:
                        {
                                bSplineIKConstraint *data= con->data;
-                               
+
                                data->points= newdataadr(fd, data->points);
-                       }
                                break;
+                       }
                        case CONSTRAINT_TYPE_KINEMATIC:
                        {
                                bKinematicConstraint *data = con->data;
@@ -2710,14 +2697,15 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
 
                                /* version patch for runtime flag, was not cleared in some case */
                                data->flag &= ~CONSTRAINT_IK_AUTO;
+                               break;
                        }
                        case CONSTRAINT_TYPE_CHILDOF:
                        {
                                /* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
                                if (con->ownspace == CONSTRAINT_SPACE_POSE)
                                        con->flag |= CONSTRAINT_SPACEONCE;
-                       }
                                break;
+                       }
                }
        }
 }
@@ -4376,6 +4364,11 @@ static void lib_link_object(FileData *fd, Main *main)
                        
                        lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
                        lib_link_modifiers(fd, ob);
+
+                       if (ob->rigidbody_constraint) {
+                               ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1);
+                               ob->rigidbody_constraint->ob2 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob2);
+                       }
                }
        }
        
@@ -4799,6 +4792,20 @@ static void direct_link_object(FileData *fd, Object *ob)
        }
        ob->bsoft = newdataadr(fd, ob->bsoft);
        ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
+       
+       ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object);
+       if (ob->rigidbody_object) {
+               RigidBodyOb *rbo = ob->rigidbody_object;
+               
+               /* must nullify the references to physics sim objects, since they no-longer exist 
+                * (and will need to be recalculated) 
+                */
+               rbo->physics_object = NULL;
+               rbo->physics_shape = NULL;
+       }
+       ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint);
+       if (ob->rigidbody_constraint)
+               ob->rigidbody_constraint->physics_constraint = NULL;
 
        link_list(fd, &ob->particlesystem);
        direct_link_particlesystems(fd, &ob->particlesystem);
@@ -5017,6 +5024,18 @@ static void lib_link_scene(FileData *fd, Main *main)
                        BKE_sequencer_update_muting(sce->ed);
                        BKE_sequencer_update_sound_bounds_all(sce);
                        
+                       
+                       /* rigidbody world relies on it's linked groups */
+                       if (sce->rigidbody_world) {
+                               RigidBodyWorld *rbw = sce->rigidbody_world;
+                               if (rbw->group)
+                                       rbw->group = newlibadr(fd, sce->id.lib, rbw->group);
+                               if (rbw->constraints)
+                                       rbw->constraints = newlibadr(fd, sce->id.lib, rbw->constraints);
+                               if (rbw->effector_weights)
+                                       rbw->effector_weights->group = newlibadr(fd, sce->id.lib, rbw->effector_weights->group);
+                       }
+                       
                        if (sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
                                composite_patch(sce->nodetree, sce);
@@ -5093,6 +5112,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
+       RigidBodyWorld *rbw;
        
        sce->theDag = NULL;
        sce->dagisvalid = 0;
@@ -5279,6 +5299,28 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        }
 
        direct_link_view_settings(fd, &sce->view_settings);
+       
+       sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world);
+       rbw = sce->rigidbody_world;
+       if (rbw) {
+               /* must nullify the reference to physics sim object, since it no-longer exist 
+                * (and will need to be recalculated) 
+                */
+               rbw->physics_world = NULL;
+               rbw->objects = NULL;
+               rbw->numbodies = 0;
+
+               /* set effector weights */
+               rbw->effector_weights = newdataadr(fd, rbw->effector_weights);
+               if (!rbw->effector_weights)
+                       rbw->effector_weights = BKE_add_effector_weights(NULL);
+
+               /* link cache */
+               direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE);
+               /* make sure simulation starts from the beginning after loading file */
+               if (rbw->pointcache)
+                       rbw->ltime = rbw->pointcache->startframe;
+       }
 }
 
 /* ************ READ WM ***************** */
@@ -5964,6 +6006,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                
                sa->handlers.first = sa->handlers.last = NULL;
                sa->type = NULL;        /* spacetype callbacks */
+               sa->region_active_win = -1;
                
                for (ar = sa->regionbase.first; ar; ar = ar->next)
                        direct_link_region(fd, ar, sa->spacetype);
@@ -6012,6 +6055,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                v3d->afterdraw_xray.first = v3d->afterdraw_xray.last = NULL;
                                v3d->afterdraw_xraytransp.first = v3d->afterdraw_xraytransp.last = NULL;
                                v3d->properties_storage = NULL;
+                               v3d->defmaterial = NULL;
                                
                                /* render can be quite heavy, set to wire on load */
                                if (v3d->drawtype == OB_RENDER)
@@ -7298,6 +7342,17 @@ static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *
        }
 }
 
+static void do_version_node_fix_translate_wrapping(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       bNode *node;
+
+       for (node = ntree->nodes.first; node; node = node->next) {
+               if (node->type == CMP_NODE_TRANSLATE && node->storage == NULL) {
+                       node->storage = MEM_callocN(sizeof(NodeTranslateData), "node translate data");
+               }
+       }
+}
+
 static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
 {
        bNode *node;
@@ -8589,11 +8644,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
                Scene *scene;
-               Image *image;
-               Tex *tex;
+               Image *image, *nimage;
+               Tex *tex, *otex;
 
                for (scene = main->scene.first; scene; scene = scene->id.next) {
                        Sequence *seq;
+                       bool set_premul = false;
 
                        SEQ_BEGIN (scene->ed, seq)
                        {
@@ -8604,21 +8660,85 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                        if (scene->r.bake_samples == 0)
                        scene->r.bake_samples = 256;
+
+                       if (scene->world) {
+                               World *world = blo_do_versions_newlibadr(fd, scene->id.lib, scene->world);
+
+                               if (is_zero_v3(&world->horr)) {
+                                       if ((world->skytype & WO_SKYBLEND) == 0 || is_zero_v3(&world->zenr)) {
+                                               set_premul = true;
+                                       }
+                               }
+                       }
+                       else
+                               set_premul = true;
+
+                       if (set_premul) {
+                               printf("2.66 versioning fix: replacing black sky with premultiplied alpha for scene %s\n", scene->id.name + 2);
+                               scene->r.alphamode = R_ALPHAPREMUL;
+                       }
                }
 
                for (image = main->image.first; image; image = image->id.next) {
                        if (image->flag & IMA_DO_PREMUL)
                                image->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+                       image->flag &= ~IMA_DONE_TAG;
                }
 
+               /* use alpha flag moved from texture to image datablock */
                for (tex = main->tex.first; tex; tex = tex->id.next) {
                        if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
                                image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
 
-                               if (image)
+                               /* skip if no image or already tested */
+                               if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
+                                       continue;
+
+                               image->flag |= IMA_DONE_TAG;
+
+                               /* we might have some textures using alpha and others not, so we check if
+                                * they exist and duplicate the image datablock if necessary */
+                               for (otex = main->tex.first; otex; otex = otex->id.next)
+                                       if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
+                                               if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
+                                                       break;
+
+                               if (otex) {
+                                       /* copy image datablock */
+                                       nimage = BKE_image_copy(main, image);
+                                       nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
+                                       nimage->id.us--;
+
+                                       /* we need to do some trickery to make file loading think
+                                        * this new datablock is part of file we're loading */
+                                       blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
+                                       nimage->id.lib = image->id.lib;
+                                       nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
+
+                                       /* assign new image, and update the users counts accordingly */
+                                       for (otex = main->tex.first; otex; otex = otex->id.next) {
+                                               if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
+                                                       if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
+                                                               if (!(otex->id.flag & LIB_NEED_LINK)) {
+                                                                       image->id.us--;
+                                                                       nimage->id.us++;
+                                                               }
+                                                               otex->ima = nimage;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               else {
+                                       /* no other textures using alpha, just set the flag */
                                        image->flag |= IMA_IGNORE_ALPHA;
+                               }
                        }
                }
+
+               for (image = main->image.first; image; image = image->id.next)
+                       image->flag &= ~IMA_DONE_TAG;
        }
 
        if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
@@ -8672,6 +8792,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       // add storage for compositor translate nodes when not existing
+       if (!MAIN_VERSION_ATLEAST(main, 265, 10)) {
+               bNodeTreeType *ntreetype;
+
+               ntreetype = ntreeGetType(NTREE_COMPOSIT);
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_translate_wrapping);
+       }
+
+
+
        // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -8913,7 +9044,7 @@ static void sort_bhead_old_map(FileData *fd)
        fd->tot_bheadmap = tot;
        if (tot == 0) return;
        
-       bhs = fd->bheadmap = MEM_mallocN(tot*sizeof(struct BHeadSort), STRINGIFY(BHeadSort));
+       bhs = fd->bheadmap = MEM_mallocN(tot * sizeof(struct BHeadSort), "BHeadSort");
        
        for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead), bhs++) {
                bhs->bhead = bhead;
@@ -9647,7 +9778,12 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
        
        if (ob->pd && ob->pd->tex)
                expand_doit(fd, mainvar, ob->pd->tex);
-       
+
+       if (ob->rigidbody_constraint) {
+               expand_doit(fd, mainvar, ob->rigidbody_constraint->ob1);
+               expand_doit(fd, mainvar, ob->rigidbody_constraint->ob2);
+       }
+
 }
 
 static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
@@ -9693,6 +9829,11 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
                }
                SEQ_END
        }
+       
+       if (sce->rigidbody_world) {
+               expand_doit(fd, mainvar, sce->rigidbody_world->group);
+               expand_doit(fd, mainvar, sce->rigidbody_world->constraints);
+       }
 
 #ifdef DURIAN_CAMERA_SWITCH
        {
@@ -9951,7 +10092,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
                        Base *base;
                        
                        /* BKE_object_add(...) messes with the selection */
-                       Object *ob = BKE_object_add_only_object(OB_EMPTY, group->id.name+2);
+                       Object *ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name+2);
                        ob->type = OB_EMPTY;
                        ob->lay = scene->lay;