307
317
void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
309
extern float Tin, Tr, Tg, Tb;
310
extern void externtex(struct MTex *mtex, float *vec);
319
float tin, tr, tg, tb, ta;
322
externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
315
324
if(paf->texmap==PAF_TEXINT) {
317
no[0]+= Tin*paf->defvec[0];
318
no[1]+= Tin*paf->defvec[1];
319
no[2]+= Tin*paf->defvec[2];
326
no[0]+= tin*paf->defvec[0];
327
no[1]+= tin*paf->defvec[1];
328
no[2]+= tin*paf->defvec[2];
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;
326
335
else { /* PAF_TEXGRAD */
329
338
co[0]+= paf->nabla;
331
no[0]+= (old-Tin)*paf->texfac;
339
externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
340
no[0]+= (old-tin)*paf->texfac;
333
342
co[0]-= paf->nabla;
334
343
co[1]+= paf->nabla;
336
no[1]+= (old-Tin)*paf->texfac;
344
externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
345
no[1]+= (old-tin)*paf->texfac;
338
347
co[1]-= paf->nabla;
339
348
co[2]+= paf->nabla;
341
no[2]+= (old-Tin)*paf->texfac;
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;
355
static int linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *labda)
357
float p[3], s[3], d[3], e1[3], e2[3], q[3];
366
if ((a > -0.000001) && (a < 0.000001)) return 0;
372
*labda = f * INPR(e2, q);
373
if ((*labda < 0.0)||(*labda > 1.0)) return 0;
376
if ((u < 0.0)||(u > 1.0)) return 0;
379
if ((v < 0.0)||((u + v) > 1.0)) return 0;
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
390
par_layer = layer the caller is in
393
void pdDoEffector(float *opco, float *force, float *speed, float cur_time, unsigned int par_layer,unsigned int flags)
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)
409
float vect_to_vert[3];
411
float f_force, distance;
413
float force_val, ffall_val;
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) */
419
for(base = G.scene->base.first; base; base= base->next) {
420
if( (base->lay & par_layer) && base->object->pd) {
424
/* checking if to continue or not */
425
if(pd->forcefield==0) continue;
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);
431
force_val = pd->f_strength;
433
if (has_ipo_code(ob->ipo, OB_PD_FFALL))
434
ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
436
ffall_val = pd->f_power;
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;
447
/* use center of object for distance calculus */
449
VECSUB(vect_to_vert, obloc, opco);
450
distance = VecLength(vect_to_vert);
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]);
457
/* wind works harder perpendicular to normal, would be nice for softbody later (ton) */
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 );
469
force[0] += force_vec[0]*f_force;
470
force[1] += force_vec[1]*f_force;
471
force[2] += force_vec[2]*f_force;
474
else if(pd->forcefield == PFIELD_FORCE) {
476
/* only use center of object */
479
/* Now calculate the gravitational force */
480
VECSUB(vect_to_vert, obloc, opco);
481
distance = VecLength(vect_to_vert);
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 );
492
else if(pd->forcefield == PFIELD_VORTEX) {
494
/* only use center of object */
497
/* Now calculate the vortex force */
498
VECSUB(vect_to_vert, obloc, opco);
499
distance = VecLength(vect_to_vert);
501
Crossf(force_vec, ob->obmat[2], vect_to_vert);
502
Normalise(force_vec);
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 );
517
static void cache_object_vertices(Object *ob)
525
if(me->totvert==0) return;
527
fp= ob->sumohandle= MEM_mallocN(3*sizeof(float)*me->totvert, "cache particles");
531
VECCOPY(fp, mvert->co);
532
Mat4MulVecfl(ob->obmat, fp);
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)
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 */
550
Object *ob, *deflection_object = NULL;
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];
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;
568
float mat[3][3], obloc[3];
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;
577
/* The first part of the code, finding the first intersected face*/
578
base= G.scene->base.first;
580
/*Only proceed for mesh object in same layer */
581
if(base->object->type==OB_MESH && (base->lay & par_layer)) {
583
/* only with deflecting set */
584
if(ob->pd && ob->pd->deflect) {
587
d_object = d_object + 1;
590
mface= def_mesh->mface;
591
a = def_mesh->totface;
594
if(ob->parent==NULL && ob->ipo==NULL) { // static
595
if(ob->sumohandle==NULL) cache_object_vertices(ob);
596
vcache= ob->sumohandle;
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;
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];
618
v1= vcache+ 3*(mface->v1);
620
v1= vcache+ 3*(mface->v2);
622
v1= vcache+ 3*(mface->v3);
624
v1= vcache+ 3*(mface->v4);
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;
639
/*Apply the objects deformation matrix*/
640
Mat3MulVecfl(mat, nv1);
641
Mat3MulVecfl(mat, nv2);
642
Mat3MulVecfl(mat, nv3);
643
Mat3MulVecfl(mat, nv4);
645
VECADD(nv1, nv1, obloc);
646
VECADD(nv2, nv2, obloc);
647
VECADD(nv3, nv3, obloc);
648
VECADD(nv4, nv4, obloc);
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) ) {
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)
668
if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
676
if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
678
ds_object = d_object;
680
deflection_object = ob;
681
deflection_face = mface;
682
if (deflected_now==1) {
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*/
708
if (has_ipo_code(deflection_object->ipo, OB_PD_PERM))
709
perm_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_PERM, cur_time);
711
perm_val = deflection_object->pd->pdef_perm;
713
perm_thresh = (float)BLI_drand() - perm_val;
714
if (perm_thresh < 0 ) {
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 */
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);
729
VECSUB(d_intersect_vect, npco, opco);
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]));
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);
741
VECSUB(vect_to_int, opco, d_intersect_co);
742
first_dist = Normalise(vect_to_int);
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)));
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];
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));
763
/*A random variation in the damping factor........ */
764
/*Get the IPO values for damping here*/
766
if (has_ipo_code(deflection_object->ipo, OB_PD_SDAMP))
767
damping = IPO_GetFloatValue(deflection_object->ipo, OB_PD_SDAMP, cur_time);
769
damping = deflection_object->pd->pdef_damp;
771
if (has_ipo_code(deflection_object->ipo, OB_PD_RDAMP))
772
rdamp_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_RDAMP, cur_time);
774
rdamp_val = deflection_object->pd->pdef_rdamp;
776
damping = damping + ((1 - damping) * ((float)BLI_drand()*rdamp_val));
777
damping = damping * damping;
778
ref_plane_mag = INPR(refl_vel,d_nvect);
780
if (damping > 0.999) damping = 0.999f;
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));
790
VECCOPY(forcec, force);
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);
810
*last_object = ds_object;
811
*last_face = ds_face;
813
/* We have the particles speed at the point of collision */
814
/* Now we want the particles speed at the current key frame */
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];
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];
826
/* And set the old co-ordinates back to the point just above the intersection */
827
VECCOPY(opco, d_i_co_above);
829
/* Finally update the time */
831
cur_time += time_before;
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 */
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))) {
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;
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]);
862
void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex, unsigned int par_layer)
348
864
Particle *pa, *opa = NULL;
349
float damp, deltalife;
865
float damp, deltalife, life;
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;
352
871
damp= 1.0f-paf->damp;
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));
362
881
/* start speed: texture */
363
882
if(mtex && paf->texfac!=0.0) {
364
883
particle_tex(mtex, paf, pa->co, pa->no);
367
886
if(paf->totkey>1) deltalife= pa->lifetime/(paf->totkey-1);
368
887
else deltalife= pa->lifetime;
373
892
b= paf->totkey-1;
376
895
pa->time= opa->time+deltalife;
897
/* set initial variables */
898
opco[0] = opa->co[0];
899
opco[1] = opa->co[1];
900
opco[2] = opa->co[2];
902
new_force[0] = force[0];
903
new_force[1] = force[1];
904
new_force[2] = force[2];
909
/* Check force field */
911
pdDoEffector(opco, new_force, new_speed, cur_time, par_layer,0);
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]);
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];
923
/* Particle deflection code */
928
VECCOPY(opno, opa->no);
929
VECCOPY(npco, pa->co);
930
VECCOPY(npno, pa->no);
933
cur_time -= deltalife;
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);
950
def_count = def_count + 1;
952
if (def_count==10) finish_defs = 0;
959
/* Only update the particle positions and speed if we had a deflection */
388
970
/* speed: texture */
389
971
if(mtex && paf->texfac!=0.0) {
844
1507
if(wav->damp==0) wav->damp= 10.0f;
846
1509
mvert= me->mvert;
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);
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)
1526
Object *ob, *deflection_object = NULL;
1528
MFace *mface, *deflection_face = NULL;
1529
float *v1, *v2, *v3, *v4, *vcache=NULL;
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;
1536
int d_object=0, d_face=0, ds_object=0, ds_face=0;
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;
1547
/* The first part of the code, finding the first intersected face*/
1548
base= G.scene->base.first;
1550
/*Only proceed for mesh object in same layer */
1551
if(base->object->type==OB_MESH && (base->lay & par_layer)) {
1553
if((vertexowner) && (ob == vertexowner)){
1554
/* if vertexowner is given
1555
* we don't want to check collision with owner object */
1559
/* only with deflecting set */
1560
if(ob->pd && ob->pd->deflect) {
1563
d_object = d_object + 1;
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 */
1570
innerfacethickness =-ob->pd->pdef_sbift;
1571
outerfacethickness =ob->pd->pdef_sboft;
1572
fa = (ff*outerfacethickness-outerfacethickness);
1576
if(ob->parent==NULL && ob->ipo==NULL) { // static
1577
if(ob->sumohandle==NULL) cache_object_vertices(ob);
1578
vcache= ob->sumohandle;
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;
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];
1601
v1= vcache+ 3*(mface->v1);
1603
v1= vcache+ 3*(mface->v2);
1605
v1= vcache+ 3*(mface->v3);
1607
v1= vcache+ 3*(mface->v4);
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;
1622
/*Apply the objects deformation matrix*/
1623
Mat3MulVecfl(mat, nv1);
1624
Mat3MulVecfl(mat, nv2);
1625
Mat3MulVecfl(mat, nv3);
1626
Mat3MulVecfl(mat, nv4);
1628
VECADD(nv1, nv1, obloc);
1629
VECADD(nv2, nv2, obloc);
1630
VECADD(nv3, nv3, obloc);
1631
VECADD(nv4, nv4, obloc);
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
1642
Crossf(d_nvect, edge2, edge1);
1643
n_mag = Normalise(d_nvect);
1644
facedist = Inpf(dv1,d_nvect);
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);
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;
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
1668
Crossf(d_nvect, edge2, edge1);
1669
n_mag = Normalise(d_nvect);
1670
facedist = Inpf(dv1,d_nvect);
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);
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;
1691
if (mode == 2){ // edge intrusion test
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) ) {
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)
1707
if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
1715
if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
1717
ds_object = d_object;
1719
deflection_object = ob;
1720
deflection_face = mface;
1721
if (deflected_now==1) {
1742
if (mode == 1){ // face
1746
if (mode == 2){ // edge intrusion test
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]));
1757
VECCOPY(facenormal,d_nvect);