~ubuntu-branches/ubuntu/lucid/blender/lucid

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/constraint.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2009-08-06 22:32:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806223219-8z4eej1u8levu4pz
Tags: 2.49a+dfsg-0ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: Build-depend on python-2.6 rather than python-2.5.
  - debian/misc/*.desktop: Add Spanish translation to .desktop 
    files.
  - debian/pyversions: 2.6.
  - debian/rules: Clean *.o of source/blender/python/api2_2x/
* New upstream release (LP: #382153).
* Refreshed patches:
  - 01_sanitize_sys.patch
  - 02_tmp_in_HOME
  - 10_use_systemwide_ftgl
  - 70_portability_platform_detection
* Removed patches merged upstream:
  - 30_fix_python_syntax_warning
  - 90_ubuntu_ffmpeg_52_changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: constraint.c 17126 2008-10-20 06:39:08Z aligorith $
 
2
 * $Id: constraint.c 19853 2009-04-21 15:38:53Z ton $
3
3
 *
4
4
 * ***** BEGIN GPL LICENSE BLOCK *****
5
5
 *
40
40
 
41
41
#include "DNA_armature_types.h"
42
42
#include "DNA_constraint_types.h"
 
43
#include "DNA_modifier_types.h"
43
44
#include "DNA_object_types.h"
44
45
#include "DNA_action_types.h"
45
46
#include "DNA_curve_types.h"
63
64
#include "BKE_global.h"
64
65
#include "BKE_library.h"
65
66
#include "BKE_idprop.h"
66
 
 
67
 
 
 
67
#include "BKE_shrinkwrap.h"
 
68
 
 
69
#ifndef DISABLE_PYTHON
68
70
#include "BPY_extern.h"
 
71
#endif
69
72
 
70
73
#include "blendef.h"
71
74
 
539
542
        float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
540
543
        float imat[3][3], tmat[3][3];
541
544
        int dgroup;
 
545
        short freeDM = 0;
542
546
        
543
547
        /* initialize target matrix using target matrix */
544
548
        Mat4CpyMat4(mat, ob->obmat);
551
555
        if ((G.obedit == ob) && (G.editMesh)) {
552
556
                /* target is in editmode, so get a special derived mesh */
553
557
                dm = CDDM_from_editmesh(G.editMesh, ob->data);
 
558
                freeDM= 1;
554
559
        }
555
560
        else {
556
 
                /* when not in EditMode, this should exist */
557
 
                dm = (DerivedMesh *)ob->derivedFinal;
 
561
                /* when not in EditMode, use the 'final' derived mesh 
 
562
                 *      - check if the custom data masks for derivedFinal mean that we can just use that
 
563
                 *        (this is more effficient + sufficient for most cases)
 
564
                 */
 
565
                if (ob->lastDataMask != CD_MASK_DERIVEDMESH) {
 
566
                        dm = mesh_get_derived_final(ob, CD_MASK_DERIVEDMESH);
 
567
                        freeDM= 1;
 
568
                }
 
569
                else 
 
570
                        dm = (DerivedMesh *)ob->derivedFinal;
558
571
        }
559
572
        
560
573
        /* only continue if there's a valid DerivedMesh */
619
632
                }
620
633
        }
621
634
        
622
 
        /* free temporary DerivedMesh created (in EditMode case) */
623
 
        if (G.editMesh) {
624
 
                if (dm) dm->release(dm);
625
 
        }
 
635
        /* free temporary DerivedMesh created */
 
636
        if (dm && freeDM) 
 
637
                dm->release(dm);
626
638
}
627
639
 
628
640
/* function that sets the given matrix based on given vertex group in lattice */
1043
1055
                n[2] = 1.0;
1044
1056
        }
1045
1057
        if (axis > 2) axis -= 3;
1046
 
        else VecMulf(n,-1);
 
1058
        else VecNegf(n);
1047
1059
 
1048
1060
        /* n specifies the transformation of the track axis */
1049
1061
        if (flags & TARGET_Z_UP) { 
1814
1826
        sizelike_evaluate /* evaluate */
1815
1827
};
1816
1828
 
 
1829
 
1817
1830
/* ----------- Python Constraint -------------- */
1818
1831
 
1819
1832
static void pycon_free (bConstraint *con)
1888
1901
                constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
1889
1902
                
1890
1903
                /* only execute target calculation if allowed */
 
1904
#ifndef DISABLE_PYTHON
1891
1905
                if (G.f & G_DOSCRIPTLINKS)
1892
1906
                        BPY_pyconstraint_target(data, ct);
 
1907
#endif
1893
1908
        }
1894
1909
        else if (ct)
1895
1910
                Mat4One(ct->matrix);
1897
1912
 
1898
1913
static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
1899
1914
{
 
1915
#ifdef DISABLE_PYTHON
 
1916
        return;
 
1917
#else
1900
1918
        bPythonConstraint *data= con->data;
1901
1919
        
1902
1920
        /* only evaluate in python if we're allowed to do so */
1913
1931
        
1914
1932
        /* Now, run the actual 'constraint' function, which should only access the matrices */
1915
1933
        BPY_pyconstraint_eval(data, cob, targets);
 
1934
#endif /* DISABLE_PYTHON */
1916
1935
}
1917
1936
 
1918
1937
static bConstraintTypeInfo CTI_PYTHON = {
2174
2193
                                        Projf(vec2, vec, cob->matrix[0]);
2175
2194
                                        VecSubf(totmat[1], vec, vec2);
2176
2195
                                        Normalize(totmat[1]);
2177
 
                                        VecMulf(totmat[1],-1);
 
2196
                                        VecNegf(totmat[1]);
2178
2197
                                        
2179
2198
                                        /* the x axis is fixed */
2180
2199
                                        totmat[0][0] = cob->matrix[0][0];
2192
2211
                                        Projf(vec2, vec, cob->matrix[0]);
2193
2212
                                        VecSubf(totmat[2], vec, vec2);
2194
2213
                                        Normalize(totmat[2]);
2195
 
                                        VecMulf(totmat[2],-1);
 
2214
                                        VecNegf(totmat[2]);
2196
2215
                                                
2197
2216
                                        /* the x axis is fixed */
2198
2217
                                        totmat[0][0] = cob->matrix[0][0];
2257
2276
                                        Projf(vec2, vec, cob->matrix[1]);
2258
2277
                                        VecSubf(totmat[0], vec, vec2);
2259
2278
                                        Normalize(totmat[0]);
2260
 
                                        VecMulf(totmat[0],-1);
 
2279
                                        VecNegf(totmat[0]);
2261
2280
                                        
2262
2281
                                        /* the y axis is fixed */
2263
2282
                                        totmat[1][0] = cob->matrix[1][0];
2275
2294
                                        Projf(vec2, vec, cob->matrix[1]);
2276
2295
                                        VecSubf(totmat[2], vec, vec2);
2277
2296
                                        Normalize(totmat[2]);
2278
 
                                        VecMulf(totmat[2],-1);
 
2297
                                        VecNegf(totmat[2]);
2279
2298
                                        
2280
2299
                                        /* the y axis is fixed */
2281
2300
                                        totmat[1][0] = cob->matrix[1][0];
2340
2359
                                        Projf(vec2, vec, cob->matrix[2]);
2341
2360
                                        VecSubf(totmat[0], vec, vec2);
2342
2361
                                        Normalize(totmat[0]);
2343
 
                                        VecMulf(totmat[0],-1);
 
2362
                                        VecNegf(totmat[0]);
2344
2363
                                        
2345
2364
                                        /* the z axis is fixed */
2346
2365
                                        totmat[2][0] = cob->matrix[2][0];
2358
2377
                                        Projf(vec2, vec, cob->matrix[2]);
2359
2378
                                        VecSubf(totmat[1], vec, vec2);
2360
2379
                                        Normalize(totmat[1]);
2361
 
                                        VecMulf(totmat[1],-1);
 
2380
                                        VecNegf(totmat[1]);
2362
2381
                                        
2363
2382
                                        /* the z axis is fixed */
2364
2383
                                        totmat[2][0] = cob->matrix[2][0];
3222
3241
        transform_evaluate /* evaluate */
3223
3242
};
3224
3243
 
 
3244
/* ---------- Shrinkwrap Constraint ----------- */
 
3245
 
 
3246
static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
 
3247
{
 
3248
        if (con && list) {
 
3249
                bShrinkwrapConstraint *data = con->data;
 
3250
                bConstraintTarget *ct;
 
3251
                
 
3252
                SINGLETARGETNS_GET_TARS(con, data->target, ct, list)
 
3253
                
 
3254
                return 1;
 
3255
        }
 
3256
        
 
3257
        return 0;
 
3258
}
 
3259
 
 
3260
 
 
3261
static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy)
 
3262
{
 
3263
        if (con && list) {
 
3264
                bShrinkwrapConstraint *data = con->data;
 
3265
                bConstraintTarget *ct= list->first;
 
3266
                
 
3267
                SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy)
 
3268
        }
 
3269
}
 
3270
 
 
3271
 
 
3272
static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
 
3273
{
 
3274
        bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
 
3275
        
 
3276
        if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) )
 
3277
        {
 
3278
                int fail = FALSE;
 
3279
                float co[3] = {0.0f, 0.0f, 0.0f};
 
3280
                float no[3] = {0.0f, 0.0f, 0.0f};
 
3281
                float dist;
 
3282
 
 
3283
                SpaceTransform transform;
 
3284
                DerivedMesh *target = object_get_derived_final(ct->tar, CD_MASK_BAREMESH);
 
3285
                BVHTreeRayHit hit;
 
3286
                BVHTreeNearest nearest;
 
3287
 
 
3288
                BVHTreeFromMesh treeData;
 
3289
                memset( &treeData, 0, sizeof(treeData) );
 
3290
 
 
3291
                nearest.index = -1;
 
3292
                nearest.dist = FLT_MAX;
 
3293
 
 
3294
                hit.index = -1;
 
3295
                hit.dist = 100000.0f;  //TODO should use FLT_MAX.. but normal projection doenst yet supports it
 
3296
 
 
3297
                Mat4One(ct->matrix);
 
3298
 
 
3299
                if(target != NULL)
 
3300
                {
 
3301
                        space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
 
3302
 
 
3303
                        switch(scon->shrinkType)
 
3304
                        {
 
3305
                                case MOD_SHRINKWRAP_NEAREST_SURFACE:
 
3306
                                case MOD_SHRINKWRAP_NEAREST_VERTEX:
 
3307
 
 
3308
                                        if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
 
3309
                                                bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6);
 
3310
                                        else
 
3311
                                                bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
 
3312
 
 
3313
                                        if(treeData.tree == NULL)
 
3314
                                        {
 
3315
                                                fail = TRUE;
 
3316
                                                break;
 
3317
                                        }
 
3318
 
 
3319
                                        space_transform_apply(&transform, co);
 
3320
 
 
3321
                                        BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
 
3322
                                        
 
3323
                                        dist = VecLenf(co, nearest.co);
 
3324
                                        VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); /* linear interpolation */
 
3325
                                        space_transform_invert(&transform, co);
 
3326
                                break;
 
3327
 
 
3328
                                case MOD_SHRINKWRAP_PROJECT:
 
3329
                                        if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f;
 
3330
                                        if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f;
 
3331
                                        if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f;
 
3332
 
 
3333
                                        if(INPR(no,no) < FLT_EPSILON)
 
3334
                                        {
 
3335
                                                fail = TRUE;
 
3336
                                                break;
 
3337
                                        }
 
3338
 
 
3339
                                        Normalize(no);
 
3340
 
 
3341
 
 
3342
                                        bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
 
3343
                                        if(treeData.tree == NULL)
 
3344
                                        {
 
3345
                                                fail = TRUE;
 
3346
                                                break;
 
3347
                                        }
 
3348
 
 
3349
                                        if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
 
3350
                                        {
 
3351
                                                fail = TRUE;
 
3352
                                                break;
 
3353
                                        }
 
3354
                                        VECCOPY(co, hit.co);
 
3355
                                break;
 
3356
                        }
 
3357
 
 
3358
                        free_bvhtree_from_mesh(&treeData);
 
3359
 
 
3360
                        target->release(target);
 
3361
 
 
3362
                        if(fail == TRUE)
 
3363
                        {
 
3364
                                /* Don't move the point */
 
3365
                                co[0] = co[1] = co[2] = 0.0f;
 
3366
                        }
 
3367
 
 
3368
                        /* co is in local object coordinates, change it to global and update target position */
 
3369
                        VecMat4MulVecfl(co, cob->matrix, co);
 
3370
                        VECCOPY(ct->matrix[3], co);
 
3371
                }
 
3372
        }
 
3373
}
 
3374
 
 
3375
static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
 
3376
{
 
3377
        bConstraintTarget *ct= targets->first;
 
3378
        
 
3379
        /* only evaluate if there is a target */
 
3380
        if (VALID_CONS_TARGET(ct))
 
3381
        {
 
3382
                VECCOPY(cob->matrix[3], ct->matrix[3]);
 
3383
        }
 
3384
}
 
3385
 
 
3386
static bConstraintTypeInfo CTI_SHRINKWRAP = {
 
3387
        CONSTRAINT_TYPE_SHRINKWRAP, /* type */
 
3388
        sizeof(bShrinkwrapConstraint), /* size */
 
3389
        "Shrinkwrap", /* name */
 
3390
        "bShrinkwrapConstraint", /* struct name */
 
3391
        NULL, /* free data */
 
3392
        NULL, /* relink data */
 
3393
        NULL, /* copy data */
 
3394
        NULL, /* new data */
 
3395
        shrinkwrap_get_tars, /* get constraint targets */
 
3396
        shrinkwrap_flush_tars, /* flush constraint targets */
 
3397
        shrinkwrap_get_tarmat, /* get a target matrix */
 
3398
        shrinkwrap_evaluate /* evaluate */
 
3399
};
 
3400
 
 
3401
 
 
3402
 
3225
3403
/* ************************* Constraints Type-Info *************************** */
3226
3404
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
3227
3405
 * and operations that involve constraint specifc code.
3253
3431
        constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT;   /* RigidBody Constraint */
3254
3432
        constraintsTypeInfo[18]= &CTI_CLAMPTO;                  /* ClampTo Constraint */        
3255
3433
        constraintsTypeInfo[19]= &CTI_TRANSFORM;                /* Transformation Constraint */
 
3434
        constraintsTypeInfo[20]= &CTI_SHRINKWRAP;               /* Shrinkwrap Constraint */
3256
3435
}
3257
3436
 
3258
3437
/* This function should be used for getting the appropriate type-info when only
3372
3551
                /* make a new copy of the constraint's data */
3373
3552
                con->data = MEM_dupallocN(con->data);
3374
3553
                
 
3554
                id_us_plus((ID *)con->ipo);
 
3555
                
3375
3556
                /* only do specific constraints if required */
3376
3557
                if (cti && cti->copy_data)
3377
3558
                        cti->copy_data(con, srccon);