a) Forces can be hidden by deflector object now (need to talk with jahka about partic...
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 18 Aug 2008 14:41:24 +0000 (14:41 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 18 Aug 2008 14:41:24 +0000 (14:41 +0000)
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle_system.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_object.c

index 2966d932a49837151bd240eff57bc3ab123c6b25..c483148e4de4a3804ce2d01d6f965cb97a9388d9 100644 (file)
@@ -119,8 +119,10 @@ FaceCollPair;
 /////////////////////////////////////////////////
 // used in modifier.c from collision.c
 /////////////////////////////////////////////////
+
 BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon );
 void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int numverts, int moving );
+
 /////////////////////////////////////////////////
 
 LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
@@ -133,6 +135,15 @@ void collision_move_object ( CollisionModifierData *collmd, float step, float pr
 void collisions_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 );
 void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 );
 
+/////////////////////////////////////////////////
+// used in effect.c
+/////////////////////////////////////////////////
+CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj);
+
+/////////////////////////////////////////////////
+
+
+
 /////////////////////////////////////////////////
 
 #endif
index cfcab54058d02885b118712453ab23baec49c7c2..b5e09d551f038f371d2a6e180e9beef136cf1112 100644 (file)
 
 #include "BKE_cloth.h"
 
-#include "DNA_group_types.h"
-#include "DNA_object_types.h"
 #include "DNA_cloth_types.h"
+#include "DNA_group_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_DerivedMesh.h"
@@ -1307,9 +1308,34 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
        for ( base = G.scene->base.first; base; base = base->next )
        {
                coll_ob = base->object;
-               collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-       
-               if ( !collmd )
+               
+               if(coll_ob->pd && coll_ob->pd->deflect)
+               {
+                       collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+               }
+               
+               if ( collmd )
+               {
+                       if(coll_ob == self)
+                               continue;
+                       
+                       if(numobj >= maxobj)
+                       {
+                               // realloc
+                               int oldmax = maxobj;
+                               CollisionModifierData **tmp;
+                               maxobj *= 2;
+                               tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+                               memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+                               MEM_freeN(objs);
+                               objs = tmp;
+                               
+                       }
+                       
+                       objs[numobj] = collmd;
+                       numobj++;
+               }
+               else
                {
                        if ( coll_ob->dup_group )
                        {
@@ -1319,8 +1345,12 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                                for ( go= group->gobject.first; go; go= go->next )
                                {
                                        coll_ob = go->ob;
-
-                                       collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+                                       collmd = NULL;
+                                       
+                                       if(coll_ob->pd && coll_ob->pd->deflect)
+                                       {
+                                               collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+                                       }
 
                                        if ( !collmd )
                                                continue;
@@ -1347,27 +1377,6 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                                        numobj++;
                                }
                        }
-               }
-               else
-               {
-                       if(coll_ob == self)
-                               continue;
-                       
-                       if(numobj >= maxobj)
-                       {
-                               // realloc
-                               int oldmax = maxobj;
-                               CollisionModifierData **tmp;
-                               maxobj *= 2;
-                               tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
-                               memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
-                               MEM_freeN(objs);
-                               objs = tmp;
-                               
-                       }
-                       
-                       objs[numobj] = collmd;
-                       numobj++;
                }       
        }
        *numcollobj = numobj;
@@ -1484,6 +1493,9 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
                        BVHTreeOverlap *overlap = NULL;
                        int result = 0;
                        
+                       if(!collmd->bvhtree)
+                               continue;
+                       
                        /* move object to position (step) in time */
                        collision_move_object ( collmd, step + dt, step );
                        
index 7620edac126f77c1912efd6a83fb4d1ab10366b2..1ab8ab757ecb9daa49f82e0f9947a7cc3482e634 100644 (file)
@@ -59,6 +59,7 @@
 #include "BKE_armature.h"
 #include "BKE_bad_level_calls.h"
 #include "BKE_blender.h"
+#include "BKE_collision.h"
 #include "BKE_constraint.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
@@ -393,6 +394,53 @@ void do_physical_effector(short type, float force_val, float distance, float fal
 }
 
 
+static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{      
+       hit->dist = -1;
+       hit->index = 1;
+}
+
+float eff_calc_visibility(Object *ob, float *co, float *dir, float cur_time)
+{
+       CollisionModifierData **collobjs = NULL;
+       int numcollobj = 0, i;
+       float norm[3], len = 0.0;
+       float visibility = 1.0;
+       
+       collobjs = get_collisionobjects(ob, &numcollobj);
+       
+       if(!collobjs)
+               return 0;
+       
+       VECCOPY(norm, dir);
+       VecMulf(norm, -1.0);
+       len = Normalize(norm);
+       
+       // check all collision objects
+       for(i = 0; i < numcollobj; i++)
+       {
+               CollisionModifierData *collmd = collobjs[i];
+               
+               if(collmd->bvhtree)
+               {
+                       BVHTreeRayHit hit;
+                       
+                       hit.index = -1;
+                       hit.dist = len + FLT_EPSILON;
+                       
+                       
+                       // check if the way is blocked
+                       if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, &hit, eff_tri_ray_hit, NULL)>=0)
+                       {
+                               visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorbation)*0.01)));
+                       }
+               }
+       }
+       
+       MEM_freeN(collobjs);
+       
+       return visibility;
+}
 
 
 /*  -------- pdDoEffectors() --------
@@ -430,7 +478,7 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
        float *obloc;
        
        float distance, vec_to_part[3];
-       float falloff;
+       float falloff, visibility;
 
        /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
        /* Check for min distance here? (yes would be cool to add that, ton) */
@@ -452,14 +500,19 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
                distance = VecLength(vec_to_part);
 
                falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);
-
+               
                if(falloff<=0.0f)
+                       continue;
+               
+               visibility = eff_calc_visibility(ob, opco, vec_to_part, cur_time);
+               
+               if((visibility*falloff)<=0.0f)
                        ;       /* don't do anything */
                else {
                        float field[3]={0,0,0}, tmp[3];
                        VECCOPY(field, force);
                        do_physical_effector(pd->forcefield,pd->f_strength,distance,
-                                                               falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
+                                                               visibility*falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
                                                                speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
                        
                        // for softbody backward compatibility
index 0375ab22909708cd0d6e53a1076548067a2befc8..995ea666380335b7a699c0d644db13cf03856e4b 100644 (file)
@@ -1405,6 +1405,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        unsigned int numverts = cloth->numverts;
        LinkNode *search = cloth->springs;
        lfVector *winvec;
+       ClothVertex *verts = cloth->verts;
 
        VECCOPY(gravity, clmd->sim_parms->gravity);
        mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
@@ -1451,7 +1452,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
                        float triunnormal[3]={0,0,0}; // not-normalized-triangle normal
                        float tmp[3]={0,0,0};
                        float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0;
-                       factor *= 0.05;
                        
                        // calculate face normal
                        if(mfaces[i].v4)
@@ -1465,24 +1465,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
                        // add wind from v1
                        VECCOPY(tmp, trinormal);
                        VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v1], triunnormal));
-                       VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor);
+                       VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor*verts[mfaces[i].v1].mass);
                        
                        // add wind from v2
                        VECCOPY(tmp, trinormal);
                        VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v2], triunnormal));
-                       VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor);
+                       VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor*verts[mfaces[i].v2].mass);
                        
                        // add wind from v3
                        VECCOPY(tmp, trinormal);
                        VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v3], triunnormal));
-                       VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor);
+                       VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor*verts[mfaces[i].v3].mass);
                        
                        // add wind from v4
                        if(mfaces[i].v4)
                        {
                                VECCOPY(tmp, trinormal);
                                VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v4], triunnormal));
-                               VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
+                               VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor*verts[mfaces[i].v4].mass);
                        }
                }
                del_lfvector(winvec);
index 1dc76296c28783d75d5164f5ca7280fc7fd6c0f6..777be445e63928a87cf90e12e31937df75b3a960 100644 (file)
@@ -5493,7 +5493,7 @@ static void collisionModifier_deformVerts(
                
                numverts = dm->getNumVerts ( dm );
                
-               if(current_time > collmd->time)
+               if((current_time > collmd->time)|| (BKE_ptcache_get_continue_physics()))
                {       
                        // check if mesh has changed
                        if(collmd->x && (numverts != collmd->numverts))
index 60fdbca20219223ecb5cd1bbad69659250b8cde0..3fae574b4131632cbf0dedc5f1be19f55e05aaf2 100644 (file)
@@ -60,6 +60,7 @@
 #include "BKE_bad_level_calls.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_displist.h"
+#include "BKE_effect.h"
 #include "BKE_particle.h"
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
index a44d9793062e3bc2e7ca445921593c64c0dd9f89..70193077b74bc452f57bc9c35a160f6e36ee75ef 100644 (file)
@@ -390,7 +390,8 @@ typedef struct CollisionModifierData {
        
        unsigned int numverts;
        unsigned int numfaces;
-       int pad;
+       short absorbation; /* used for forces, in % */
+       short pad;
        float time;             /* cfra time of modifier */
        struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
 } CollisionModifierData;
index 71b29478f8990f0fafb33c6554ccf8e4b35ee7d5..521ab83d3a6138250e3c7546a16e1eace911ede5 100644 (file)
@@ -3279,6 +3279,8 @@ static void object_panel_collision(Object *ob)
                uiDefBut(block, LABEL, 0, "",160,160,150,2, NULL, 0.0, 0, 0, 0, "");
                
                if(pd->deflect) {
+                       CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType ( ob, eModifierType_Collision );
+                       
                        uiDefBut(block, LABEL, 0, "Particle Interaction",                       10,135,310,20, NULL, 0.0, 0, 0, 0, "");
 
                        uiBlockBeginAlign(block);
@@ -3294,12 +3296,18 @@ static void object_panel_collision(Object *ob)
                        uiDefBut(block, LABEL, 0, "Soft Body and Cloth Interaction",                    10,65,310,20, NULL, 0.0, 0, 0, 0, "");
 
                        uiBlockBeginAlign(block);
-                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:",       10,45,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
-                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 10,25,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
-                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 10, 5,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 10,45,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
+                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160, 45,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
                        uiBlockEndAlign(block);
+                       uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:",       10,25,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
 
-                       uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 170,45,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
+                       uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 160,25,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
+                       
+                       // collision options
+                       if(collmd)
+                       {
+                               uiDefButS(block, NUM, B_FIELD_CHANGE, "Absoption: ",    10,0,150,20, &collmd->absorbation, 0.0, 100, 1, 2, "How much of effector force gets lost during collision with this object (in percent).");
+                       }
                }
        }
 }