~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  effect.c 
2
 
 * 
3
 
 * 
4
 
 * $Id: effect.c,v 1.11 2004/03/20 22:55:37 zuster Exp $
 
1
/*  effect.c
 
2
 * 
 
3
 * 
 
4
 * $Id: effect.c,v 1.45 2005/06/06 18:52:07 bjornmose Exp $
5
5
 *
6
6
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7
7
 *
39
39
#include "DNA_listBase.h"
40
40
#include "DNA_effect_types.h"
41
41
#include "DNA_object_types.h"
 
42
#include "DNA_object_force.h"
42
43
#include "DNA_mesh_types.h"
43
44
#include "DNA_meshdata_types.h"
44
45
#include "DNA_material_types.h"
47
48
#include "DNA_texture_types.h"
48
49
#include "DNA_scene_types.h"
49
50
#include "DNA_lattice_types.h"
 
51
#include "DNA_ipo_types.h"
50
52
 
51
53
#include "BLI_blenlib.h"
52
54
#include "BLI_arithb.h"
53
55
#include "BLI_rand.h"
54
56
 
55
 
#include "BKE_utildefines.h"
 
57
#include "BKE_action.h"
56
58
#include "BKE_bad_level_calls.h"
 
59
#include "BKE_blender.h"
 
60
#include "BKE_constraint.h"
 
61
#include "BKE_deform.h"
 
62
#include "BKE_displist.h"
 
63
#include "BKE_DerivedMesh.h"
 
64
#include "BKE_effect.h"
57
65
#include "BKE_global.h"
 
66
#include "BKE_ipo.h"
 
67
#include "BKE_key.h"
 
68
#include "BKE_lattice.h"
 
69
#include "BKE_mesh.h"
58
70
#include "BKE_material.h"
59
 
#include "BKE_effect.h"
60
 
#include "BKE_key.h"
61
 
#include "BKE_ipo.h"
 
71
#include "BKE_main.h"
 
72
#include "BKE_object.h"
62
73
#include "BKE_screen.h"
63
 
#include "BKE_blender.h"
64
 
#include "BKE_object.h"
65
 
#include "BKE_displist.h"
66
 
#include "BKE_lattice.h"
 
74
#include "BKE_utildefines.h"
 
75
 
 
76
#include "render.h"  // externtex, bad level call (ton)
67
77
 
68
78
 
69
79
#ifdef HAVE_CONFIG_H
157
167
Effect *copy_effect(Effect *eff) 
158
168
{
159
169
        Effect *effn;
160
 
        
 
170
 
161
171
        effn= MEM_dupallocN(eff);
162
172
        if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
163
173
 
282
292
        /* first find the first particlekey */
283
293
        a= (int)((paf->totkey-1)*(ctime-pa->time)/pa->lifetime);
284
294
        if(a>=paf->totkey) a= paf->totkey-1;
 
295
        else if(a<0) a= 0;
285
296
        
286
297
        pa+= a;
287
298
        
303
314
 
304
315
}
305
316
 
306
 
 
307
317
void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
308
318
{                               
309
 
        extern float Tin, Tr, Tg, Tb;
310
 
        extern void externtex(struct MTex *mtex, float *vec);
 
319
        float tin, tr, tg, tb, ta;
311
320
        float old;
312
321
        
313
 
        externtex(mtex, co);
314
 
        
 
322
        externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
 
323
 
315
324
        if(paf->texmap==PAF_TEXINT) {
316
 
                Tin*= paf->texfac;
317
 
                no[0]+= Tin*paf->defvec[0];
318
 
                no[1]+= Tin*paf->defvec[1];
319
 
                no[2]+= Tin*paf->defvec[2];
 
325
                tin*= paf->texfac;
 
326
                no[0]+= tin*paf->defvec[0];
 
327
                no[1]+= tin*paf->defvec[1];
 
328
                no[2]+= tin*paf->defvec[2];
320
329
        }
321
330
        else if(paf->texmap==PAF_TEXRGB) {
322
 
                no[0]+= (Tr-0.5f)*paf->texfac;
323
 
                no[1]+= (Tg-0.5f)*paf->texfac;
324
 
                no[2]+= (Tb-0.5f)*paf->texfac;
 
331
                no[0]+= (tr-0.5f)*paf->texfac;
 
332
                no[1]+= (tg-0.5f)*paf->texfac;
 
333
                no[2]+= (tb-0.5f)*paf->texfac;
325
334
        }
326
335
        else {  /* PAF_TEXGRAD */
327
336
                
328
 
                old= Tin;
 
337
                old= tin;
329
338
                co[0]+= paf->nabla;
330
 
                externtex(mtex, co);
331
 
                no[0]+= (old-Tin)*paf->texfac;
 
339
                externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
 
340
                no[0]+= (old-tin)*paf->texfac;
332
341
                
333
342
                co[0]-= paf->nabla;
334
343
                co[1]+= paf->nabla;
335
 
                externtex(mtex, co);
336
 
                no[1]+= (old-Tin)*paf->texfac;
 
344
                externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
 
345
                no[1]+= (old-tin)*paf->texfac;
337
346
                
338
347
                co[1]-= paf->nabla;
339
348
                co[2]+= paf->nabla;
340
 
                externtex(mtex, co);
341
 
                no[2]+= (old-Tin)*paf->texfac;
342
 
                
343
 
        }
344
 
}
345
 
 
346
 
void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex)
 
349
                externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
 
350
                no[2]+= (old-tin)*paf->texfac;
 
351
                
 
352
        }
 
353
}
 
354
 
 
355
static int linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *labda)
 
356
{
 
357
        float p[3], s[3], d[3], e1[3], e2[3], q[3];
 
358
        float a, f, u, v;
 
359
        
 
360
        VECSUB(e1, v1, v0);
 
361
        VECSUB(e2, v2, v0);
 
362
        VECSUB(d, p2, p1);
 
363
        
 
364
        Crossf(p, d, e2);
 
365
        a = INPR(e1, p);
 
366
        if ((a > -0.000001) && (a < 0.000001)) return 0;
 
367
        f = 1.0f/a;
 
368
        
 
369
        VECSUB(s, p1, v0);
 
370
        
 
371
        Crossf(q, s, e1);
 
372
        *labda = f * INPR(e2, q);
 
373
        if ((*labda < 0.0)||(*labda > 1.0)) return 0;
 
374
        
 
375
        u = f * INPR(s, p);
 
376
        if ((u < 0.0)||(u > 1.0)) return 0;
 
377
        
 
378
        v = f * INPR(d, q);
 
379
        if ((v < 0.0)||((u + v) > 1.0)) return 0;
 
380
        
 
381
        return 1;
 
382
}
 
383
 
 
384
/*  -------- pdDoEffector() --------
 
385
    generic force/speed system, now used for particles and softbodies
 
386
        opco            = global coord, as input
 
387
    force               = force accumulator
 
388
    speed               = speed accumulator
 
389
    cur_time    = in frames
 
390
    par_layer   = layer the caller is in
 
391
 
 
392
*/
 
393
void pdDoEffector(float *opco, float *force, float *speed, float cur_time, unsigned int par_layer,unsigned int flags)
 
394
{
 
395
/*
 
396
        Modifies the force on a particle according to its
 
397
        relation with the effector object
 
398
        Different kind of effectors include:
 
399
                Forcefields: Gravity-like attractor
 
400
                (force power is related to the inverse of distance to the power of a falloff value)
 
401
                Vortex fields: swirling effectors
 
402
                (particles rotate around Z-axis of the object. otherwise, same relation as)
 
403
                (Forcefields, but this is not done through a force/acceleration)
 
404
        
 
405
*/
 
406
        Object *ob;
 
407
        Base *base;
 
408
        PartDeflect *pd;
 
409
        float vect_to_vert[3];
 
410
        float force_vec[3];
 
411
        float f_force, distance;
 
412
        float *obloc;
 
413
        float force_val, ffall_val;
 
414
        short cur_frame;
 
415
 
 
416
        /* Cycle through objects, get total of (1/(gravity_strength * dist^gravity_power)) */
 
417
        /* Check for min distance here? (yes would be cool to add that, ton) */
 
418
        
 
419
        for(base = G.scene->base.first; base; base= base->next) {
 
420
                if( (base->lay & par_layer) && base->object->pd) {
 
421
                        ob= base->object;
 
422
                        pd= ob->pd;
 
423
                        
 
424
                        /* checking if to continue or not */
 
425
                        if(pd->forcefield==0) continue;
 
426
                        
 
427
                        /* Get IPO force strength and fall off values here */
 
428
                        if (has_ipo_code(ob->ipo, OB_PD_FSTR))
 
429
                                force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
 
430
                        else 
 
431
                                force_val = pd->f_strength;
 
432
                        
 
433
                        if (has_ipo_code(ob->ipo, OB_PD_FFALL)) 
 
434
                                ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
 
435
                        else 
 
436
                                ffall_val = pd->f_power;
 
437
                        
 
438
                        
 
439
                        /* Need to set r.cfra for paths (investigate, ton) (uses ob->ctime now, ton) */
 
440
                        if(ob->ctime!=cur_time) {
 
441
                                cur_frame = G.scene->r.cfra;
 
442
                                G.scene->r.cfra = (short)cur_time;
 
443
                                where_is_object_time(ob, cur_time);
 
444
                                G.scene->r.cfra = cur_frame;
 
445
                        }
 
446
                        
 
447
                        /* use center of object for distance calculus */
 
448
                        obloc= ob->obmat[3];
 
449
                        VECSUB(vect_to_vert, obloc, opco);
 
450
                        distance = VecLength(vect_to_vert);
 
451
                        
 
452
                        if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist)
 
453
                                ;       /* don't do anything */
 
454
                        else if(pd->forcefield == PFIELD_WIND) {
 
455
                                VECCOPY(force_vec, ob->obmat[2]);
 
456
                                
 
457
                                /* wind works harder perpendicular to normal, would be nice for softbody later (ton) */
 
458
                                
 
459
                                /* Limit minimum distance to vertex so that */
 
460
                                /* the force is not too big */
 
461
                                if (distance < 0.001) distance = 0.001f;
 
462
                                f_force = (force_val)*(1/(1000 * (float)pow((double)distance, (double)ffall_val)));
 
463
                                if(flags &&PE_WIND_AS_SPEED){
 
464
                                speed[0] -= (force_vec[0] * f_force );
 
465
                                speed[1] -= (force_vec[1] * f_force );
 
466
                                speed[2] -= (force_vec[2] * f_force );
 
467
                                }
 
468
                                else{
 
469
                                force[0] += force_vec[0]*f_force;
 
470
                                force[1] += force_vec[1]*f_force;
 
471
                                force[2] += force_vec[2]*f_force;
 
472
                                }
 
473
                        }
 
474
                        else if(pd->forcefield == PFIELD_FORCE) {
 
475
                                
 
476
                                /* only use center of object */
 
477
                                obloc= ob->obmat[3];
 
478
 
 
479
                                /* Now calculate the gravitational force */
 
480
                                VECSUB(vect_to_vert, obloc, opco);
 
481
                                distance = VecLength(vect_to_vert);
 
482
 
 
483
                                /* Limit minimum distance to vertex so that */
 
484
                                /* the force is not too big */
 
485
                                if (distance < 0.001) distance = 0.001f;
 
486
                                f_force = (force_val)*(1/(1000 * (float)pow((double)distance, (double)ffall_val)));
 
487
                                force[0] += (vect_to_vert[0] * f_force );
 
488
                                force[1] += (vect_to_vert[1] * f_force );
 
489
                                force[2] += (vect_to_vert[2] * f_force );
 
490
 
 
491
                        }
 
492
                        else if(pd->forcefield == PFIELD_VORTEX) {
 
493
 
 
494
                                /* only use center of object */
 
495
                                obloc= ob->obmat[3];
 
496
 
 
497
                                /* Now calculate the vortex force */
 
498
                                VECSUB(vect_to_vert, obloc, opco);
 
499
                                distance = VecLength(vect_to_vert);
 
500
 
 
501
                                Crossf(force_vec, ob->obmat[2], vect_to_vert);
 
502
                                Normalise(force_vec);
 
503
 
 
504
                                /* Limit minimum distance to vertex so that */
 
505
                                /* the force is not too big */
 
506
                                if (distance < 0.001) distance = 0.001f;
 
507
                                f_force = (force_val)*(1/(100 * (float)pow((double)distance, (double)ffall_val)));
 
508
                                speed[0] -= (force_vec[0] * f_force );
 
509
                                speed[1] -= (force_vec[1] * f_force );
 
510
                                speed[2] -= (force_vec[2] * f_force );
 
511
 
 
512
                        }
 
513
                }
 
514
        }
 
515
}
 
516
 
 
517
static void cache_object_vertices(Object *ob)
 
518
{
 
519
        Mesh *me;
 
520
        MVert *mvert;
 
521
        float *fp;
 
522
        int a;
 
523
        
 
524
        me= ob->data;
 
525
        if(me->totvert==0) return;
 
526
 
 
527
        fp= ob->sumohandle= MEM_mallocN(3*sizeof(float)*me->totvert, "cache particles");
 
528
        mvert= me->mvert;
 
529
        a= me->totvert;
 
530
        while(a--) {
 
531
                VECCOPY(fp, mvert->co);
 
532
                Mat4MulVecfl(ob->obmat, fp);
 
533
                mvert++;
 
534
                fp+= 3;
 
535
        }
 
536
}
 
537
 
 
538
int pdDoDeflection(float opco[3], float npco[3], float opno[3],
 
539
        float npno[3], float life, float force[3], int def_depth,
 
540
        float cur_time, unsigned int par_layer, int *last_object,
 
541
                int *last_face, int *same_face)
 
542
{
 
543
        /* Particle deflection code */
 
544
        /* The code is in two sections: the first part checks whether a particle has            */
 
545
        /* intersected a face of a deflector mesh, given its old and new co-ords, opco and npco */
 
546
        /* and which face it hit first                                                          */
 
547
        /* The second part calculates the new co-ordinates given that collision and updates     */
 
548
        /* the new co-ordinates accordingly */
 
549
        Base *base;
 
550
        Object *ob, *deflection_object = NULL;
 
551
        Mesh *def_mesh;
 
552
        MFace *mface, *deflection_face = NULL;
 
553
        float *v1, *v2, *v3, *v4, *vcache=NULL;
 
554
        float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3];
 
555
        float dv1[3], dv2[3], dv3[3];
 
556
        float vect_to_int[3], refl_vel[3];
 
557
        float d_intersect_co[3], d_intersect_vect[3], d_nvect[3], d_i_co_above[3];
 
558
        float forcec[3];
 
559
        float k_point3, dist_to_plane;
 
560
        float first_dist, ref_plane_mag;
 
561
        float dk_plane=0, dk_point1=0;
 
562
        float icalctop, icalcbot, n_mag;
 
563
        float mag_iv, x_m,y_m,z_m;
 
564
        float damping, perm_thresh;
 
565
        float perm_val, rdamp_val;
 
566
        int a, deflected=0, deflected_now=0;
 
567
        float t,t2, min_t;
 
568
        float mat[3][3], obloc[3];
 
569
        short cur_frame;
 
570
        float time_before, time_after;
 
571
        float force_mag_norm;
 
572
        int d_object=0, d_face=0, ds_object=0, ds_face=0;
 
573
 
 
574
        first_dist = 200000;
 
575
        min_t = 200000;
 
576
 
 
577
        /* The first part of the code, finding the first intersected face*/
 
578
        base= G.scene->base.first;
 
579
        while (base) {
 
580
                /*Only proceed for mesh object in same layer */
 
581
                if(base->object->type==OB_MESH && (base->lay & par_layer)) {
 
582
                        ob= base->object;
 
583
                        /* only with deflecting set */
 
584
                        if(ob->pd && ob->pd->deflect) {
 
585
                                def_mesh= ob->data;
 
586
                        
 
587
                                d_object = d_object + 1;
 
588
 
 
589
                                d_face = d_face + 1;
 
590
                                mface= def_mesh->mface;
 
591
                                a = def_mesh->totface;
 
592
                                
 
593
                                
 
594
                                if(ob->parent==NULL && ob->ipo==NULL) { // static
 
595
                                        if(ob->sumohandle==NULL) cache_object_vertices(ob);
 
596
                                        vcache= ob->sumohandle;
 
597
                                }
 
598
                                else {
 
599
                                        /*Find out where the object is at this time*/
 
600
                                        cur_frame = G.scene->r.cfra;
 
601
                                        G.scene->r.cfra = (short)cur_time;
 
602
                                        where_is_object_time(ob, cur_time);
 
603
                                        G.scene->r.cfra = cur_frame;
 
604
                                        
 
605
                                        /*Pass the values from ob->obmat to mat*/
 
606
                                        /*and the location values to obloc           */
 
607
                                        Mat3CpyMat4(mat,ob->obmat);
 
608
                                        obloc[0] = ob->obmat[3][0];
 
609
                                        obloc[1] = ob->obmat[3][1];
 
610
                                        obloc[2] = ob->obmat[3][2];
 
611
                                        vcache= NULL;
 
612
 
 
613
                                }
 
614
                                
 
615
                                while (a--) {
 
616
 
 
617
                                        if(vcache) {
 
618
                                                v1= vcache+ 3*(mface->v1);
 
619
                                                VECCOPY(nv1, v1);
 
620
                                                v1= vcache+ 3*(mface->v2);
 
621
                                                VECCOPY(nv2, v1);
 
622
                                                v1= vcache+ 3*(mface->v3);
 
623
                                                VECCOPY(nv3, v1);
 
624
                                                v1= vcache+ 3*(mface->v4);
 
625
                                                VECCOPY(nv4, v1);
 
626
                                        }
 
627
                                        else {
 
628
                                                /* Calculate the global co-ordinates of the vertices*/
 
629
                                                v1= (def_mesh->mvert+(mface->v1))->co;
 
630
                                                v2= (def_mesh->mvert+(mface->v2))->co;
 
631
                                                v3= (def_mesh->mvert+(mface->v3))->co;
 
632
                                                v4= (def_mesh->mvert+(mface->v4))->co;
 
633
        
 
634
                                                VECCOPY(nv1, v1);
 
635
                                                VECCOPY(nv2, v2);
 
636
                                                VECCOPY(nv3, v3);
 
637
                                                VECCOPY(nv4, v4);
 
638
        
 
639
                                                /*Apply the objects deformation matrix*/
 
640
                                                Mat3MulVecfl(mat, nv1);
 
641
                                                Mat3MulVecfl(mat, nv2);
 
642
                                                Mat3MulVecfl(mat, nv3);
 
643
                                                Mat3MulVecfl(mat, nv4);
 
644
        
 
645
                                                VECADD(nv1, nv1, obloc);
 
646
                                                VECADD(nv2, nv2, obloc);
 
647
                                                VECADD(nv3, nv3, obloc);
 
648
                                                VECADD(nv4, nv4, obloc);
 
649
                                        }
 
650
                                        
 
651
                                        deflected_now = 0;
 
652
 
 
653
                                                
 
654
                                                
 
655
//                                      t= 0.5; // this is labda of line, can use it optimize quad intersection
 
656
// sorry but no .. see below (BM)                                       
 
657
                                        if( linetriangle(opco, npco, nv1, nv2, nv3, &t) ) {
 
658
                                                if (t < min_t) {
 
659
                                                        deflected = 1;
 
660
                                                        deflected_now = 1;
 
661
                                                }
 
662
                                        }
 
663
//                                      else if (mface->v4 && (t>=0.0 && t<=1.0)) {
 
664
// no, you can't skip testing the other triangle
 
665
// it might give a smaller t on (close to) the edge .. this is numerics not esoteric maths :)
 
666
// note: the 2 triangles don't need to share a plane ! (BM)
 
667
                                        if (mface->v4) {
 
668
                                                if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
 
669
                                                        if (t2 < min_t) {
 
670
                                                                deflected = 1;
 
671
                                                                deflected_now = 2;
 
672
                                                        }
 
673
                                                }
 
674
                                        }
 
675
                                        
 
676
                                        if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
 
677
                        min_t = t;
 
678
                        ds_object = d_object;
 
679
                                                ds_face = d_face;
 
680
                                                deflection_object = ob;
 
681
                                                deflection_face = mface;
 
682
                                                if (deflected_now==1) {
 
683
                        min_t = t;
 
684
                                                        VECCOPY(dv1, nv1);
 
685
                                                        VECCOPY(dv2, nv2);
 
686
                                                        VECCOPY(dv3, nv3);
 
687
                                                }
 
688
                                                else {
 
689
                        min_t = t2;
 
690
                                                        VECCOPY(dv1, nv1);
 
691
                                                        VECCOPY(dv2, nv3);
 
692
                                                        VECCOPY(dv3, nv4);
 
693
                                                }
 
694
                                        }
 
695
                                        mface++;
 
696
                                }
 
697
                        }
 
698
                }
 
699
                base = base->next;
 
700
        }
 
701
 
 
702
 
 
703
        /* Here's the point to do the permeability calculation */
 
704
        /* Set deflected to 0 if a random number is below the value */
 
705
        /* Get the permeability IPO here*/
 
706
        if (deflected) {
 
707
                
 
708
                if (has_ipo_code(deflection_object->ipo, OB_PD_PERM)) 
 
709
                        perm_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_PERM, cur_time);
 
710
                else 
 
711
                        perm_val = deflection_object->pd->pdef_perm;
 
712
 
 
713
                perm_thresh =  (float)BLI_drand() - perm_val;
 
714
                if (perm_thresh < 0 ) {
 
715
                        deflected = 0;
 
716
                }
 
717
        }
 
718
 
 
719
        /* Now for the second part of the deflection code - work out the new speed */
 
720
        /* and position of the particle if a collision occurred */
 
721
        if (deflected) {
 
722
        VECSUB(edge1, dv1, dv2);
 
723
                VECSUB(edge2, dv3, dv2);
 
724
                Crossf(d_nvect, edge2, edge1);
 
725
                n_mag = Normalise(d_nvect);
 
726
                dk_plane = INPR(d_nvect, nv1);
 
727
                dk_point1 = INPR(d_nvect,opco);
 
728
 
 
729
                VECSUB(d_intersect_vect, npco, opco);
 
730
 
 
731
                d_intersect_co[0] = opco[0] + (min_t * (npco[0] - opco[0]));
 
732
                d_intersect_co[1] = opco[1] + (min_t * (npco[1] - opco[1]));
 
733
                d_intersect_co[2] = opco[2] + (min_t * (npco[2] - opco[2]));
 
734
                
 
735
                d_i_co_above[0] = (d_intersect_co[0] + (0.001f * d_nvect[0]));
 
736
                d_i_co_above[1] = (d_intersect_co[1] + (0.001f * d_nvect[1]));
 
737
                d_i_co_above[2] = (d_intersect_co[2] + (0.001f * d_nvect[2]));
 
738
                mag_iv = Normalise(d_intersect_vect);
 
739
                VECCOPY(npco, d_intersect_co);
 
740
                
 
741
                VECSUB(vect_to_int, opco, d_intersect_co);
 
742
                first_dist = Normalise(vect_to_int);
 
743
 
 
744
                /* Work out the lengths of time before and after collision*/
 
745
                time_before = (life*(first_dist / (mag_iv)));
 
746
                time_after =  (life*((mag_iv - first_dist) / (mag_iv)));
 
747
 
 
748
                /* We have to recalculate what the speed would have been at the */
 
749
                /* point of collision, not the key frame time */
 
750
                npno[0]= opno[0] + time_before*force[0];
 
751
                npno[1]= opno[1] + time_before*force[1];
 
752
                npno[2]= opno[2] + time_before*force[2];
 
753
 
 
754
 
 
755
                /* Reflect the speed vector in the face */
 
756
                x_m = (2 * npno[0] * d_nvect[0]);
 
757
                y_m = (2 * npno[1] * d_nvect[1]);
 
758
                z_m = (2 * npno[2] * d_nvect[2]);
 
759
                refl_vel[0] = npno[0] - (d_nvect[0] * (x_m + y_m + z_m));
 
760
                refl_vel[1] = npno[1] - (d_nvect[1] * (x_m + y_m + z_m));
 
761
                refl_vel[2] = npno[2] - (d_nvect[2] * (x_m + y_m + z_m));
 
762
 
 
763
                /*A random variation in the damping factor........ */
 
764
                /*Get the IPO values for damping here*/
 
765
                
 
766
                if (has_ipo_code(deflection_object->ipo, OB_PD_SDAMP)) 
 
767
                        damping = IPO_GetFloatValue(deflection_object->ipo, OB_PD_SDAMP, cur_time);
 
768
                else 
 
769
                        damping = deflection_object->pd->pdef_damp;
 
770
                
 
771
                if (has_ipo_code(deflection_object->ipo, OB_PD_RDAMP)) 
 
772
                        rdamp_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_RDAMP, cur_time);
 
773
                else 
 
774
                        rdamp_val = deflection_object->pd->pdef_rdamp;
 
775
 
 
776
                damping = damping + ((1 - damping) * ((float)BLI_drand()*rdamp_val));
 
777
                damping = damping * damping;
 
778
        ref_plane_mag = INPR(refl_vel,d_nvect);
 
779
 
 
780
                if (damping > 0.999) damping = 0.999f;
 
781
 
 
782
                /* Now add in the damping force - only damp in the direction of */
 
783
                /* the faces normal vector */
 
784
                npno[0] = (refl_vel[0] - (d_nvect[0] * ref_plane_mag * damping));
 
785
                npno[1] = (refl_vel[1] - (d_nvect[1] * ref_plane_mag * damping));
 
786
                npno[2] = (refl_vel[2] - (d_nvect[2] * ref_plane_mag * damping));
 
787
 
 
788
                /* Now reset opno */
 
789
                VECCOPY(opno,npno);
 
790
                VECCOPY(forcec, force);
 
791
 
 
792
                /* If the particle has bounced more than four times on the same */
 
793
                /* face within this cycle (depth > 4, same face > 4 )           */
 
794
                /* Then set the force to be only that component of the force    */
 
795
                /* in the same direction as the face normal                     */
 
796
                /* i.e. subtract the component of the force in the direction    */
 
797
                /* of the face normal from the actual force                     */
 
798
                if ((ds_object == *last_object) && (ds_face == *last_face)) {
 
799
                        /* Increment same_face */
 
800
                        *same_face = *same_face + 1;
 
801
                        if ((*same_face > 3) && (def_depth > 3)) {
 
802
                force_mag_norm = INPR(forcec, d_nvect);
 
803
                forcec[0] = forcec[0] - (d_nvect[0] * force_mag_norm);
 
804
                forcec[1] = forcec[1] - (d_nvect[1] * force_mag_norm);
 
805
                forcec[2] = forcec[2] - (d_nvect[2] * force_mag_norm);
 
806
                        }
 
807
                }
 
808
                else *same_face = 1;
 
809
 
 
810
                *last_object = ds_object;
 
811
                *last_face = ds_face;
 
812
 
 
813
                /* We have the particles speed at the point of collision    */
 
814
                /* Now we want the particles speed at the current key frame */
 
815
 
 
816
                npno[0]= npno[0] + time_after*forcec[0];
 
817
                npno[1]= npno[1] + time_after*forcec[1];
 
818
                npno[2]= npno[2] + time_after*forcec[2];
 
819
 
 
820
                /* Now we have to recalculate pa->co for the remainder*/
 
821
                /* of the time since the intersect*/
 
822
                npco[0]= npco[0] + time_after*npno[0];
 
823
                npco[1]= npco[1] + time_after*npno[1];
 
824
                npco[2]= npco[2] + time_after*npno[2];
 
825
 
 
826
                /* And set the old co-ordinates back to the point just above the intersection */
 
827
                VECCOPY(opco, d_i_co_above);
 
828
 
 
829
                /* Finally update the time */
 
830
                life = time_after;
 
831
                cur_time += time_before;
 
832
 
 
833
                /* The particle may have fallen through the face again by now!!*/
 
834
                /* So check if the particle has changed sides of the plane compared*/
 
835
                /* the co-ordinates at the last keyframe*/
 
836
                /* But only do this as a last resort, if we've got to the end of the */
 
837
                /* number of collisions allowed */
 
838
                if (def_depth==9) {
 
839
                        k_point3 = INPR(d_nvect,npco);
 
840
                        if (((dk_plane > k_point3) && (dk_plane < dk_point1))||((dk_plane < k_point3) && (dk_plane > dk_point1))) {
 
841
 
 
842
                                /* Yup, the pesky particle may have fallen through a hole!!! */
 
843
                /* So we'll cheat a bit and move the particle along the normal vector */
 
844
                /* until it's just the other side of the plane */
 
845
                icalctop = (dk_plane - d_nvect[0]*npco[0] - d_nvect[1]*npco[1] - d_nvect[2]*npco[2]);
 
846
                icalcbot = (d_nvect[0]*d_nvect[0] + d_nvect[1]*d_nvect[1] + d_nvect[2]*d_nvect[2]);
 
847
                dist_to_plane = icalctop / icalcbot;
 
848
 
 
849
                /*  Now just increase the distance a little to place */
 
850
                /* the point the other side of the plane */
 
851
                dist_to_plane *= 1.1f;
 
852
                npco[0]= npco[0] + (dist_to_plane * d_nvect[0]);
 
853
                npco[1]= npco[1] + (dist_to_plane * d_nvect[1]);
 
854
                npco[2]= npco[2] + (dist_to_plane * d_nvect[2]);
 
855
 
 
856
                        }
 
857
                }
 
858
        }
 
859
        return deflected;
 
860
}
 
861
 
 
862
void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex, unsigned int par_layer)
347
863
{
348
864
        Particle *pa, *opa = NULL;
349
 
        float damp, deltalife;
350
 
        int b, rt1, rt2;
351
 
        
 
865
        float damp, deltalife, life;
 
866
        float cur_time;
 
867
        float opco[3], opno[3], npco[3], npno[3], new_force[3], new_speed[3];
 
868
        int b, rt1, rt2, deflected, deflection, finish_defs, def_count;
 
869
        int last_ob, last_fc, same_fc;
 
870
 
352
871
        damp= 1.0f-paf->damp;
353
872
        pa= part;
354
 
        
 
873
 
355
874
        /* start speed: random */
356
875
        if(paf->randfac!=0.0) {
357
876
                pa->no[0]+= (float)(paf->randfac*( BLI_drand() -0.5));
358
877
                pa->no[1]+= (float)(paf->randfac*( BLI_drand() -0.5));
359
878
                pa->no[2]+= (float)(paf->randfac*( BLI_drand() -0.5));
360
879
        }
361
 
        
 
880
 
362
881
        /* start speed: texture */
363
882
        if(mtex && paf->texfac!=0.0) {
364
883
                particle_tex(mtex, paf, pa->co, pa->no);
365
884
        }
366
 
        
 
885
 
367
886
        if(paf->totkey>1) deltalife= pa->lifetime/(paf->totkey-1);
368
887
        else deltalife= pa->lifetime;
369
888
 
370
889
        opa= pa;
371
890
        pa++;
372
 
                
 
891
 
373
892
        b= paf->totkey-1;
374
893
        while(b--) {
375
894
                /* new time */
376
895
                pa->time= opa->time+deltalife;
377
896
 
 
897
                /* set initial variables                                */
 
898
                opco[0] = opa->co[0];
 
899
                opco[1] = opa->co[1];
 
900
                opco[2] = opa->co[2];
 
901
 
 
902
                new_force[0] = force[0];
 
903
                new_force[1] = force[1];
 
904
                new_force[2] = force[2];
 
905
                new_speed[0] = 0.0;
 
906
                new_speed[1] = 0.0;
 
907
                new_speed[2] = 0.0;
 
908
 
 
909
                /* Check force field */
 
910
                cur_time = pa->time;
 
911
                pdDoEffector(opco, new_force, new_speed, cur_time, par_layer,0);
 
912
 
378
913
                /* new location */
379
 
                pa->co[0]= opa->co[0] + deltalife*opa->no[0];
380
 
                pa->co[1]= opa->co[1] + deltalife*opa->no[1];
381
 
                pa->co[2]= opa->co[2] + deltalife*opa->no[2];
 
914
                pa->co[0]= opa->co[0] + deltalife * (opa->no[0] + new_speed[0] + 0.5f*new_force[0]);
 
915
                pa->co[1]= opa->co[1] + deltalife * (opa->no[1] + new_speed[1] + 0.5f*new_force[1]);
 
916
                pa->co[2]= opa->co[2] + deltalife * (opa->no[2] + new_speed[2] + 0.5f*new_force[2]);
382
917
 
383
918
                /* new speed */
384
 
                pa->no[0]= opa->no[0] + deltalife*force[0];
385
 
                pa->no[1]= opa->no[1] + deltalife*force[1];
386
 
                pa->no[2]= opa->no[2] + deltalife*force[2];
 
919
                pa->no[0]= opa->no[0] + deltalife*new_force[0];
 
920
                pa->no[1]= opa->no[1] + deltalife*new_force[1];
 
921
                pa->no[2]= opa->no[2] + deltalife*new_force[2];
 
922
 
 
923
                /* Particle deflection code                             */
 
924
                deflection = 0;
 
925
                finish_defs = 1;
 
926
                def_count = 0;
 
927
 
 
928
                VECCOPY(opno, opa->no);
 
929
                VECCOPY(npco, pa->co);
 
930
                VECCOPY(npno, pa->no);
 
931
 
 
932
                life = deltalife;
 
933
                cur_time -= deltalife;
 
934
 
 
935
                last_ob = -1;
 
936
                last_fc = -1;
 
937
                same_fc = 0;
 
938
 
 
939
                /* First call the particle deflection check for the particle moving   */
 
940
                /* between the old co-ordinates and the new co-ordinates              */
 
941
                /* If a deflection occurs, call the code again, this time between the */
 
942
                /* intersection point and the updated new co-ordinates                */
 
943
                /* Bail out if we've done the calculation 10 times - this seems ok     */
 
944
        /* for most scenes I've tested */
 
945
                while (finish_defs) {
 
946
                        deflected =  pdDoDeflection(opco, npco, opno, npno, life, new_force,
 
947
                                                        def_count, cur_time, par_layer,
 
948
                                                        &last_ob, &last_fc, &same_fc);
 
949
                        if (deflected) {
 
950
                                def_count = def_count + 1;
 
951
                                deflection = 1;
 
952
                                if (def_count==10) finish_defs = 0;
 
953
                        }
 
954
                        else {
 
955
                                finish_defs = 0;
 
956
                        }
 
957
                }
 
958
 
 
959
                /* Only update the particle positions and speed if we had a deflection */
 
960
                if (deflection) {
 
961
                        pa->co[0] = npco[0];
 
962
                        pa->co[1] = npco[1];
 
963
                        pa->co[2] = npco[2];
 
964
                        pa->no[0] = npno[0];
 
965
                        pa->no[1] = npno[1];
 
966
                        pa->no[2] = npno[2];
 
967
                }
 
968
 
387
969
 
388
970
                /* speed: texture */
389
971
                if(mtex && paf->texfac!=0.0) {
395
977
                        pa->no[2]*= damp;
396
978
                }
397
979
        
 
980
 
 
981
 
398
982
                opa= pa;
399
983
                pa++;
400
984
                /* opa is used later on too! */
428
1012
                                        pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
429
1013
                                }
430
1014
                                pa->mat_nr= paf->mat[depth];
431
 
                                
432
 
                                make_particle_keys(depth+1, b, paf, pa, force, deform, mtex);
 
1015
 
 
1016
                                make_particle_keys(depth+1, b, paf, pa, force, deform, mtex, par_layer);
433
1017
                        }
434
1018
                }
435
1019
        }
436
1020
}
437
1021
 
438
 
void init_mv_jit(float *jit, int num,float seed2)
 
1022
void init_mv_jit(float *jit, int num,int seed2)
439
1023
{
440
1024
        float *jit2, x, rad1, rad2, rad3;
441
1025
        int i, num2;
472
1056
}
473
1057
 
474
1058
 
475
 
void give_mesh_mvert(Mesh *me, int nr, float *co, short *no, float seed2)
 
1059
static void give_mesh_mvert(Mesh *me, DispListMesh *dlm, int nr, float *co, short *no, int seed2)
476
1060
{
477
1061
        static float *jit=0;
478
1062
        static int jitlevel=1;
479
 
        MVert *mvert;
480
 
        MFace *mface;
 
1063
        MVert *mvert, *mvertbase=NULL;
 
1064
        MFace *mface, *mfacebase=NULL;
481
1065
        float u, v, *v1, *v2, *v3, *v4;
482
 
        int curface, curjit;
 
1066
        int totface=0, totvert=0, curface, curjit;
483
1067
        short *n1, *n2, *n3, *n4;
484
1068
        
485
1069
        /* signal */
489
1073
                return;
490
1074
        }
491
1075
        
492
 
        if(me->totface==0 || nr<me->totvert) {
493
 
                mvert= me->mvert + (nr % me->totvert);
 
1076
        if(dlm) {
 
1077
                mvertbase= dlm->mvert;
 
1078
                mfacebase= dlm->mface;
 
1079
                totface= dlm->totface;
 
1080
                totvert= dlm->totvert;
 
1081
        }
 
1082
        
 
1083
        if(totvert==0) {
 
1084
                mvertbase= me->mvert;
 
1085
                mfacebase= me->mface;
 
1086
                totface= me->totface;
 
1087
                totvert= me->totvert;
 
1088
        }
 
1089
        
 
1090
        if(totface==0 || nr<totvert) {
 
1091
                mvert= mvertbase + (nr % totvert);
494
1092
                VECCOPY(co, mvert->co);
495
1093
                VECCOPY(no, mvert->no);
496
1094
        }
497
1095
        else {
498
 
                
499
 
                nr-= me->totvert;
 
1096
 
 
1097
                nr-= totvert;
500
1098
                
501
1099
                if(jit==0) {
502
 
                        jitlevel= nr/me->totface;
 
1100
                        jitlevel= nr/totface;
503
1101
                        if(jitlevel==0) jitlevel= 1;
504
1102
                        if(jitlevel>100) jitlevel= 100;
505
 
                        
 
1103
 
506
1104
                        jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
507
1105
                        init_mv_jit(jit, jitlevel,seed2);
508
1106
                        
509
1107
                }
510
1108
 
511
 
                curjit= nr/me->totface;
 
1109
                curjit= nr/totface;
512
1110
                curjit= curjit % jitlevel;
513
1111
 
514
 
                curface= nr % me->totface;
 
1112
                curface= nr % totface;
515
1113
                
516
 
                mface= me->mface;
 
1114
                mface= mfacebase;
517
1115
                mface+= curface;
518
 
                
519
 
                v1= (me->mvert+(mface->v1))->co;
520
 
                v2= (me->mvert+(mface->v2))->co;
521
 
                n1= (me->mvert+(mface->v1))->no;
522
 
                n2= (me->mvert+(mface->v2))->no;
 
1116
 
 
1117
                v1= (mvertbase+(mface->v1))->co;
 
1118
                v2= (mvertbase+(mface->v2))->co;
 
1119
                n1= (mvertbase+(mface->v1))->no;
 
1120
                n2= (mvertbase+(mface->v2))->no;
523
1121
                if(mface->v3==0) {
524
 
                        v3= (me->mvert+(mface->v2))->co;
525
 
                        v4= (me->mvert+(mface->v1))->co;
526
 
                        n3= (me->mvert+(mface->v2))->no;
527
 
                        n4= (me->mvert+(mface->v1))->no;
 
1122
                        v3= (mvertbase+(mface->v2))->co;
 
1123
                        v4= (mvertbase+(mface->v1))->co;
 
1124
                        n3= (mvertbase+(mface->v2))->no;
 
1125
                        n4= (mvertbase+(mface->v1))->no;
528
1126
                }
529
1127
                else if(mface->v4==0) {
530
 
                        v3= (me->mvert+(mface->v3))->co;
531
 
                        v4= (me->mvert+(mface->v1))->co;
532
 
                        n3= (me->mvert+(mface->v3))->no;
533
 
                        n4= (me->mvert+(mface->v1))->no;
 
1128
                        v3= (mvertbase+(mface->v3))->co;
 
1129
                        v4= (mvertbase+(mface->v1))->co;
 
1130
                        n3= (mvertbase+(mface->v3))->no;
 
1131
                        n4= (mvertbase+(mface->v1))->no;
534
1132
                }
535
1133
                else {
536
 
                        v3= (me->mvert+(mface->v3))->co;
537
 
                        v4= (me->mvert+(mface->v4))->co;
538
 
                        n3= (me->mvert+(mface->v3))->no;
539
 
                        n4= (me->mvert+(mface->v4))->no;
 
1134
                        v3= (mvertbase+(mface->v3))->co;
 
1135
                        v4= (mvertbase+(mface->v4))->co;
 
1136
                        n3= (mvertbase+(mface->v3))->no;
 
1137
                        n4= (mvertbase+(mface->v4))->no;
540
1138
                }
541
1139
 
542
1140
                u= jit[2*curjit];
556
1154
 
557
1155
void build_particle_system(Object *ob)
558
1156
{
 
1157
        Base *base;
559
1158
        Object *par;
560
1159
        PartEff *paf;
561
1160
        Particle *pa;
563
1162
        MVert *mvert;
564
1163
        MTex *mtexmove=0;
565
1164
        Material *ma;
 
1165
        DispListMesh *dlm;
566
1166
        float framelenont, ftime, dtime, force[3], imat[3][3], vec[3];
567
1167
        float fac, prevobmat[4][4], sfraont, co[3];
568
1168
        int deform=0, a, cur, cfraont, cfralast, totpart;
569
1169
        short no[3];
570
 
        
 
1170
 
571
1171
        if(ob->type!=OB_MESH) return;
572
1172
        me= ob->data;
573
1173
        if(me->totvert==0) return;
574
 
        
 
1174
 
575
1175
        ma= give_current_material(ob, 1);
576
1176
        if(ma) {
577
1177
                mtexmove= ma->mtex[7];
578
1178
        }
579
 
        
 
1179
 
580
1180
        paf= give_parteff(ob);
581
 
        if(paf==0) return;
 
1181
        if(paf==NULL) return;
582
1182
 
583
1183
        waitcursor(1);
584
 
        
 
1184
 
585
1185
        disable_speed_curve(1);
586
1186
        
 
1187
        /* warning! we cannot call this when modifier is active! */
 
1188
        mesh_modifier(ob, 's');
 
1189
 
587
1190
        /* generate all particles */
588
1191
        if(paf->keys) MEM_freeN(paf->keys);
589
 
        paf->keys= 0;
590
 
        new_particle(paf);      
 
1192
        paf->keys= NULL;
 
1193
        new_particle(paf);
 
1194
 
 
1195
        /* reset deflector cache, sumohandle is free, but its still sorta abuse... (ton) */
 
1196
        for(base= G.scene->base.first; base; base= base->next) {
 
1197
                base->object->sumohandle= NULL;
 
1198
        }
591
1199
 
592
1200
        cfraont= G.scene->r.cfra;
593
1201
        cfralast= -1000;
595
1203
        G.scene->r.framelen= 1.0;
596
1204
        sfraont= ob->sf;
597
1205
        ob->sf= 0.0;
598
 
        
 
1206
 
599
1207
        /* mult generations? */
600
1208
        totpart= paf->totpart;
601
1209
        for(a=0; a<PAF_MAXMULT; a++) {
608
1216
 
609
1217
        ftime= paf->sta;
610
1218
        dtime= (paf->end - paf->sta)/totpart;
611
 
        
 
1219
 
612
1220
        /* remember full hierarchy */
613
1221
        par= ob;
614
1222
        while(par) {
615
1223
                pushdata(par, sizeof(Object));
616
1224
                par= par->parent;
617
1225
        }
 
1226
        
 
1227
        /* for static particles, calculate system on current frame */
 
1228
        if(ma) do_mat_ipo(ma);
618
1229
 
619
1230
        /* set it all at first frame */
620
1231
        G.scene->r.cfra= cfralast= (int)floor(ftime);
624
1235
                do_ob_key(par);
625
1236
                par= par->parent;
626
1237
        }
627
 
        do_mat_ipo(ma);
628
1238
        
629
1239
        if((paf->flag & PAF_STATIC)==0) {
 
1240
                if(ma) do_mat_ipo(ma);  // nor for static
 
1241
                
630
1242
                where_is_object(ob);
631
1243
                Mat4CpyMat4(prevobmat, ob->obmat);
632
1244
                Mat4Invert(ob->imat, ob->obmat);
644
1256
        force[1]= paf->force[1]*0.05f;
645
1257
        force[2]= paf->force[2]*0.05f;
646
1258
        
647
 
        deform= (ob->parent && ob->parent->type==OB_LATTICE);
648
 
        if(deform) init_latt_deform(ob->parent, 0);
 
1259
        if( paf->flag & PAF_STATIC ) deform= 0;
 
1260
        else {
 
1261
                deform= (ob->parent && ob->parent->type==OB_LATTICE);
 
1262
                if(deform) init_latt_deform(ob->parent, 0);
 
1263
        }
649
1264
        
650
1265
        /* init */
651
 
        give_mesh_mvert(me, totpart, co, no,paf->seed);
 
1266
        if (mesh_uses_displist(me)) {
 
1267
                DerivedMesh *dm = mesh_get_derived(ob);
 
1268
 
 
1269
                dlm = dm->convertToDispListMesh(dm);
 
1270
        } else {
 
1271
                dlm = NULL;
 
1272
        }
 
1273
 
 
1274
        give_mesh_mvert(me, dlm, totpart, co, no, paf->seed);
652
1275
        
 
1276
        if(G.f & G_DEBUG) {
 
1277
                printf("\n");
 
1278
                printf("Calculating particles......... \n");
 
1279
        }
653
1280
        for(a=0; a<totpart; a++, ftime+=dtime) {
654
1281
                
655
1282
                pa= new_particle(paf);
656
1283
                pa->time= ftime;
657
1284
                
 
1285
                if(G.f & G_DEBUG) {
 
1286
                        int b, c;
 
1287
                        
 
1288
                        c = totpart/100;
 
1289
                        if (c==0){
 
1290
                                c = 1;
 
1291
                        }
 
1292
 
 
1293
                        b=(a%c);
 
1294
                        if (b==0) {
 
1295
                                printf("\r Particle: %d / %d ", a, totpart);
 
1296
                                fflush(stdout);
 
1297
                        }
 
1298
                }
658
1299
                /* set ob at correct time */
659
1300
                
660
1301
                if((paf->flag & PAF_STATIC)==0) {
661
 
                
 
1302
 
662
1303
                        cur= (int)floor(ftime) + 1 ;            /* + 1 has a reason: (obmat/prevobmat) otherwise comet-tails start too late */
663
1304
                        if(cfralast != cur) {
664
1305
                                G.scene->r.cfra= cfralast= cur;
665
1306
        
666
1307
                                /* added later: blur? */
667
1308
                                bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
668
 
                                
 
1309
 
669
1310
                                par= ob;
670
1311
                                while(par) {
671
1312
                                        /* do_ob_ipo(par); */
672
1313
                                        par->ctime= -1234567.0;
673
1314
                                        do_ob_key(par);
 
1315
                                        if(par->type==OB_ARMATURE) {
 
1316
                                                do_all_actions(par);    // only does this object actions
 
1317
                                                clear_object_constraint_status(par);    // mysterious call, otherwise do_actions doesnt work???
 
1318
                                        }
674
1319
                                        par= par->parent;
675
1320
                                }
676
 
                                do_mat_ipo(ma);
 
1321
                                if(ma) do_mat_ipo(ma);
677
1322
                                Mat4CpyMat4(prevobmat, ob->obmat);
678
1323
                                where_is_object(ob);
679
1324
                                Mat4Invert(ob->imat, ob->obmat);
681
1326
                        }
682
1327
                }
683
1328
                /* get coordinates */
684
 
                if(paf->flag & PAF_FACE) give_mesh_mvert(me, a, co, no,paf->seed);
 
1329
                if(paf->flag & PAF_FACE) give_mesh_mvert(me, dlm, a, co, no, paf->seed);
685
1330
                else {
686
1331
                        mvert= me->mvert + (a % me->totvert);
687
1332
                        VECCOPY(co, mvert->co);
698
1343
                        Mat4MulVecfl(prevobmat, vec);
699
1344
                        
700
1345
                        /* first start speed: object */
701
 
                        VecSubf(pa->no, pa->co, vec);
 
1346
                        VECSUB(pa->no, pa->co, vec);
702
1347
                        VecMulf(pa->no, paf->obfac);
703
1348
                        
704
1349
                        /* calculate the correct inter-frame */ 
718
1363
                
719
1364
                        Normalise(vec);
720
1365
                        VecMulf(vec, paf->normfac);
721
 
                        VecAddf(pa->no, pa->no, vec);
 
1366
                        VECADD(pa->no, pa->no, vec);
722
1367
                }
723
1368
                pa->lifetime= paf->lifetime;
724
1369
                if(paf->randlife!=0.0) {
726
1371
                }
727
1372
                pa->mat_nr= 1;
728
1373
                
729
 
                make_particle_keys(0, a, paf, pa, force, deform, mtexmove);
 
1374
                make_particle_keys(0, a, paf, pa, force, deform, mtexmove, ob->lay);
730
1375
        }
731
1376
        
 
1377
        if(G.f & G_DEBUG) {
 
1378
                printf("\r Particle: %d / %d \n", totpart, totpart);
 
1379
                fflush(stdout);
 
1380
        }       
732
1381
        if(deform) end_latt_deform();
733
1382
                
734
1383
        /* restore */
735
1384
        G.scene->r.cfra= cfraont;
736
1385
        G.scene->r.framelen= framelenont;
737
 
        give_mesh_mvert(0, 0, 0, 0,paf->seed);
738
 
 
 
1386
        give_mesh_mvert(0, 0, 0, 0, 0,paf->seed);
739
1387
 
740
1388
        /* put hierarchy back */
741
1389
        par= ob;
743
1391
                popfirst(par);
744
1392
                /* do not do ob->ipo: keep insertkey */
745
1393
                do_ob_key(par);
 
1394
                
 
1395
                if(par->type==OB_ARMATURE) {
 
1396
                        do_all_actions(par);    // only does this object actions
 
1397
                        clear_object_constraint_status(par);    // mysterious call, otherwise do_actions doesnt work???
 
1398
                }
746
1399
                par= par->parent;
747
1400
        }
748
1401
 
 
1402
        /* reset deflector cache */
 
1403
        for(base= G.scene->base.first; base; base= base->next) {
 
1404
                if(base->object->sumohandle) {
 
1405
                        MEM_freeN(base->object->sumohandle);
 
1406
                        base->object->sumohandle= NULL;
 
1407
                }
 
1408
        }
 
1409
 
749
1410
        /* restore: AFTER popfirst */
750
1411
        ob->sf= sfraont;
751
1412
 
 
1413
        if(ma) do_mat_ipo(ma);  // set back on current time
752
1414
        disable_speed_curve(0);
 
1415
        
 
1416
        mesh_modifier(ob, 'e');
753
1417
 
754
1418
        waitcursor(0);
755
1419
 
 
1420
        if (dlm) {
 
1421
                displistmesh_free(dlm);
 
1422
        }
756
1423
}
757
1424
 
758
1425
/* ************* WAVE **************** */
806
1473
        }
807
1474
}
808
1475
 
809
 
void object_wave(Object *ob)
 
1476
/* return 1 if deformed
 
1477
   Note: it works on mvert now, so assumes to be callied in modifier stack \
 
1478
*/
 
1479
int object_wave(Object *ob)
810
1480
{
811
1481
        WaveEff *wav;
812
 
        DispList *dl;
813
1482
        Mesh *me;
814
1483
        MVert *mvert;
815
 
        float *fp, ctime;
816
 
        int a, first;
 
1484
        float ctime;
 
1485
        int a;
817
1486
        
818
1487
        /* is there a wave */
819
1488
        wav= ob->effect.first;
821
1490
                if(wav->type==EFF_WAVE) break;
822
1491
                wav= wav->next;
823
1492
        }
824
 
        if(wav==0) return;
 
1493
        if(wav==NULL) return 0;
825
1494
        
826
1495
        if(ob->type==OB_MESH) {
827
1496
 
828
1497
                ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
829
 
                first= 1;
830
1498
                
831
1499
                me= ob->data;
832
 
                dl= find_displist_create(&ob->disp, DL_VERTS);
833
 
 
834
 
                if(dl->verts) MEM_freeN(dl->verts);
835
 
                dl->nr= me->totvert;
836
 
                dl->verts= MEM_mallocN(3*sizeof(float)*me->totvert, "wave");
837
1500
 
838
1501
                wav= ob->effect.first;
839
1502
                while(wav) {
844
1507
                                if(wav->damp==0) wav->damp= 10.0f;
845
1508
                                
846
1509
                                mvert= me->mvert;
847
 
                                fp= dl->verts;
848
1510
                                
849
 
                                for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
850
 
                                        if(first) VECCOPY(fp, mvert->co);
851
 
                                        calc_wave_deform(wav, ctime, fp);
 
1511
                                for(a=0; a<me->totvert; a++, mvert++) {
 
1512
                                        calc_wave_deform(wav, ctime, mvert->co);
852
1513
                                }
853
 
                                first= 0;
854
1514
                        }
855
1515
                        wav= wav->next;
856
1516
                }
857
1517
        }
858
 
}
 
1518
        return 1;
 
1519
}
 
1520
 
 
1521
int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
 
1522
                                                        float facenormal[3], float *damp, float force[3], int mode,
 
1523
                                                        float cur_time, unsigned int par_layer,struct Object *vertexowner)
 
1524
{
 
1525
        Base *base;
 
1526
        Object *ob, *deflection_object = NULL;
 
1527
        Mesh *def_mesh;
 
1528
        MFace *mface, *deflection_face = NULL;
 
1529
        float *v1, *v2, *v3, *v4, *vcache=NULL;
 
1530
        float mat[3][3];
 
1531
        float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], obloc[3];
 
1532
        float dv1[3], dv2[3], dv3[3];
 
1533
        float facedist,n_mag,t,t2, min_t,force_mag_norm;
 
1534
        int a, deflected=0, deflected_now=0;
 
1535
        short cur_frame;
 
1536
        int d_object=0, d_face=0, ds_object=0, ds_face=0;
 
1537
        
 
1538
        // i'm going to rearrange it to declaration rules when WIP is finished (BM)
 
1539
        float innerfacethickness = -0.5f;
 
1540
        float outerfacethickness = 0.2f;
 
1541
        float ee = 5.0f;
 
1542
        float ff = 0.1f;
 
1543
        float fa;
 
1544
        
 
1545
        min_t = 200000;
 
1546
        
 
1547
        /* The first part of the code, finding the first intersected face*/
 
1548
        base= G.scene->base.first;
 
1549
        while (base) {
 
1550
                /*Only proceed for mesh object in same layer */
 
1551
                if(base->object->type==OB_MESH && (base->lay & par_layer)) {
 
1552
                        ob= base->object;
 
1553
                        if((vertexowner) && (ob == vertexowner)){ 
 
1554
                        /* if vertexowner is given 
 
1555
                                * we don't want to check collision with owner object */ 
 
1556
                                base = base->next;
 
1557
                                continue;
 
1558
                        }
 
1559
                        /* only with deflecting set */
 
1560
                        if(ob->pd && ob->pd->deflect) {
 
1561
                                def_mesh= ob->data;
 
1562
                                
 
1563
                                d_object = d_object + 1;
 
1564
                                
 
1565
                                d_face = d_face + 1;
 
1566
                                mface= def_mesh->mface;
 
1567
                                a = def_mesh->totface;
 
1568
                                /* need to have user control for that since it depends on model scale */
 
1569
                                
 
1570
                                innerfacethickness =-ob->pd->pdef_sbift;
 
1571
                                outerfacethickness =ob->pd->pdef_sboft;
 
1572
                                fa = (ff*outerfacethickness-outerfacethickness);
 
1573
                                fa *= fa;
 
1574
                                fa = 1.0f/fa;
 
1575
                                
 
1576
                                if(ob->parent==NULL && ob->ipo==NULL) { // static
 
1577
                                        if(ob->sumohandle==NULL) cache_object_vertices(ob);
 
1578
                                        vcache= ob->sumohandle;
 
1579
                                }
 
1580
                                else {
 
1581
                                        /*Find out where the object is at this time*/
 
1582
                                        cur_frame = G.scene->r.cfra;
 
1583
                                        G.scene->r.cfra = (short)cur_time;
 
1584
                                        where_is_object_time(ob, cur_time);
 
1585
                                        G.scene->r.cfra = cur_frame;
 
1586
                                        
 
1587
                                        /*Pass the values from ob->obmat to mat*/
 
1588
                                        /*and the location values to obloc           */
 
1589
                                        Mat3CpyMat4(mat,ob->obmat);
 
1590
                                        obloc[0] = ob->obmat[3][0];
 
1591
                                        obloc[1] = ob->obmat[3][1];
 
1592
                                        obloc[2] = ob->obmat[3][2];
 
1593
                                        /* not cachable */
 
1594
                                        vcache= NULL;
 
1595
                                        
 
1596
                                }
 
1597
                                
 
1598
                                while (a--) {
 
1599
                                        
 
1600
                                        if(vcache) {
 
1601
                                                v1= vcache+ 3*(mface->v1);
 
1602
                                                VECCOPY(nv1, v1);
 
1603
                                                v1= vcache+ 3*(mface->v2);
 
1604
                                                VECCOPY(nv2, v1);
 
1605
                                                v1= vcache+ 3*(mface->v3);
 
1606
                                                VECCOPY(nv3, v1);
 
1607
                                                v1= vcache+ 3*(mface->v4);
 
1608
                                                VECCOPY(nv4, v1);
 
1609
                                        }
 
1610
                                        else {
 
1611
                                                /* Calculate the global co-ordinates of the vertices*/
 
1612
                                                v1= (def_mesh->mvert+(mface->v1))->co;
 
1613
                                                v2= (def_mesh->mvert+(mface->v2))->co;
 
1614
                                                v3= (def_mesh->mvert+(mface->v3))->co;
 
1615
                                                v4= (def_mesh->mvert+(mface->v4))->co;
 
1616
                                                
 
1617
                                                VECCOPY(nv1, v1);
 
1618
                                                VECCOPY(nv2, v2);
 
1619
                                                VECCOPY(nv3, v3);
 
1620
                                                VECCOPY(nv4, v4);
 
1621
                                                
 
1622
                                                /*Apply the objects deformation matrix*/
 
1623
                                                Mat3MulVecfl(mat, nv1);
 
1624
                                                Mat3MulVecfl(mat, nv2);
 
1625
                                                Mat3MulVecfl(mat, nv3);
 
1626
                                                Mat3MulVecfl(mat, nv4);
 
1627
                                                
 
1628
                                                VECADD(nv1, nv1, obloc);
 
1629
                                                VECADD(nv2, nv2, obloc);
 
1630
                                                VECADD(nv3, nv3, obloc);
 
1631
                                                VECADD(nv4, nv4, obloc);
 
1632
                                        }
 
1633
                                        
 
1634
                                        deflected_now = 0;
 
1635
                                        
 
1636
                                        if (mode == 1){ // face intrusion test
 
1637
                                                // switch origin to be nv2
 
1638
                                                VECSUB(edge1, nv1, nv2);
 
1639
                                                VECSUB(edge2, nv3, nv2);
 
1640
                                                VECSUB(dv1,opco,nv2); // abuse dv1 to have vertex in question at *origin* of triangle
 
1641
                                                
 
1642
                                                Crossf(d_nvect, edge2, edge1);
 
1643
                                                n_mag = Normalise(d_nvect);
 
1644
                                                facedist = Inpf(dv1,d_nvect);
 
1645
                                                
 
1646
                                                if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){                
 
1647
                                                        dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
 
1648
                                                        dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
 
1649
                                                        dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
 
1650
                                                        if ( linetriangle( opco, dv2, nv1, nv2, nv3, &t)){
 
1651
                                                                force_mag_norm =(float)exp(-ee*facedist);
 
1652
                                                                if (facedist > outerfacethickness*ff)
 
1653
                                                                        force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
 
1654
                                                                
 
1655
                                                                force[0] += force_mag_norm*d_nvect[0] ;
 
1656
                                                                force[1] += force_mag_norm*d_nvect[1] ;
 
1657
                                                                force[2] += force_mag_norm*d_nvect[2] ;
 
1658
                                                                *damp=ob->pd->pdef_sbdamp;
 
1659
                                                                deflected = 2;
 
1660
                                                        }
 
1661
                                                }               
 
1662
                                                if (mface->v4){ // quad
 
1663
                                                        // switch origin to be nv4
 
1664
                                                        VECSUB(edge1, nv3, nv4);
 
1665
                                                        VECSUB(edge2, nv1, nv4);
 
1666
                                                        VECSUB(dv1,opco,nv4); // abuse dv1 to have vertex in question at *origin* of triangle
 
1667
                                                        
 
1668
                                                        Crossf(d_nvect, edge2, edge1);
 
1669
                                                        n_mag = Normalise(d_nvect);
 
1670
                                                        facedist = Inpf(dv1,d_nvect);
 
1671
                                                        
 
1672
                                                        if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
 
1673
                                                                dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
 
1674
                                                                dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
 
1675
                                                                dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
 
1676
                                                                if ( linetriangle( opco, dv2, nv1, nv3, nv4, &t)){
 
1677
                                                                        force_mag_norm =(float)exp(-ee*facedist);
 
1678
                                                                        if (facedist > outerfacethickness*ff)
 
1679
                                                                                force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
 
1680
                                                                        
 
1681
                                                                        force[0] += force_mag_norm*d_nvect[0] ;
 
1682
                                                                        force[1] += force_mag_norm*d_nvect[1] ;
 
1683
                                                                        force[2] += force_mag_norm*d_nvect[2] ;
 
1684
                                                                        *damp=ob->pd->pdef_sbdamp;
 
1685
                                                                        deflected = 2;
 
1686
                                                                }
 
1687
                                                        }
 
1688
                                                        
 
1689
                                                }
 
1690
                                        }
 
1691
                                        if (mode == 2){ // edge intrusion test
 
1692
                                                
 
1693
                                                
 
1694
                                                //t= 0.5;       // this is labda of line, can use it optimize quad intersection
 
1695
                                                // sorry but no .. see below (BM)                                       
 
1696
                                                if( linetriangle(opco, npco, nv1, nv2, nv3, &t) ) {
 
1697
                                                        if (t < min_t) {
 
1698
                                                                deflected = 1;
 
1699
                                                                deflected_now = 1;
 
1700
                                                        }
 
1701
                                                }
 
1702
                                                //                                      else if (mface->v4 && (t>=0.0 && t<=1.0)) {
 
1703
                                                // no, you can't skip testing the other triangle
 
1704
                                                // it might give a smaller t on (close to) the edge .. this is numerics not esoteric maths :)
 
1705
                                                // note: the 2 triangles don't need to share a plane ! (BM)
 
1706
                                                if (mface->v4) {
 
1707
                                                        if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
 
1708
                                                                if (t2 < min_t) {
 
1709
                                                                        deflected = 1;
 
1710
                                                                        deflected_now = 2;
 
1711
                                                                }
 
1712
                                                        }
 
1713
                                                }
 
1714
                                                
 
1715
                                                if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
 
1716
                                                        min_t = t;
 
1717
                                                        ds_object = d_object;
 
1718
                                                        ds_face = d_face;
 
1719
                                                        deflection_object = ob;
 
1720
                                                        deflection_face = mface;
 
1721
                                                        if (deflected_now==1) {
 
1722
                                                                min_t = t;
 
1723
                                                                VECCOPY(dv1, nv1);
 
1724
                                                                VECCOPY(dv2, nv2);
 
1725
                                                                VECCOPY(dv3, nv3);
 
1726
                                                        }
 
1727
                                                        else {
 
1728
                                                                min_t = t2;
 
1729
                                                                VECCOPY(dv1, nv1);
 
1730
                                                                VECCOPY(dv2, nv3);
 
1731
                                                                VECCOPY(dv3, nv4);
 
1732
                                                        }
 
1733
                                                }
 
1734
                                        }  
 
1735
                                        mface++;
 
1736
                                }
 
1737
                        }
 
1738
                }
 
1739
                base = base->next;
 
1740
        } // while (base)
 
1741
        
 
1742
        if (mode == 1){ // face 
 
1743
                return deflected;
 
1744
        }
 
1745
        
 
1746
        if (mode == 2){ // edge intrusion test
 
1747
                if (deflected) {
 
1748
                        VECSUB(edge1, dv1, dv2);
 
1749
                        VECSUB(edge2, dv3, dv2);
 
1750
                        Crossf(d_nvect, edge2, edge1);
 
1751
                        n_mag = Normalise(d_nvect);
 
1752
                        // return point of intersection
 
1753
                        colco[0] = opco[0] + (min_t * (npco[0] - opco[0]));
 
1754
                        colco[1] = opco[1] + (min_t * (npco[1] - opco[1]));
 
1755
                        colco[2] = opco[2] + (min_t * (npco[2] - opco[2]));
 
1756
                        
 
1757
                        VECCOPY(facenormal,d_nvect);                                    
 
1758
                }
 
1759
        }
 
1760
        return deflected;
 
1761
}
 
1762