40 const float co_test[3],
41 const void *user_data)
43 const float *normal =
static_cast<const float *
>(user_data);
85 float priority = 0.0f,
len = 0.0f;
100 if (gabr->
ob == eob) {
103 if (cur->pd && cur->pd->forcefield ==
PFIELD_BOID) {
128 else if (temp > priority) {
145 if (eff ==
nullptr && gabr->
ob) {
147 temp_eff.
ob = gabr->
ob;
198 if (len2 > 0.0f && efd.
distance - surface < len2) {
199 len2 = (efd.
distance - surface) / len2;
217 KDTreeNearest_3d *ptn =
nullptr;
219 float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
220 float co1[3], vel1[3], co2[3], vel2[3];
221 float len, t, inp, t_min = 2.0f;
222 int n, neighbors = 0, nearest = 0;
244 if (coll->ob == bpa->
ground) {
248 col.current = coll->ob;
249 col.md = coll->collmd;
251 if (
col.md &&
col.md->bvhtree) {
263 if (hit.
index >= 0) {
264 t = hit.
dist /
col.original_ray_length;
289 neighbors = BLI_kdtree_3d_range_search_with_len_squared_cb(bbd->
sim->
psys->
tree,
297 for (n = 1; n < neighbors; n++) {
313 if (t > 0.0f && t < t_min) {
344 neighbors = BLI_kdtree_3d_range_search_with_len_squared_cb(epsys->
tree,
353 for (n = 0; n < neighbors; n++) {
369 if (t > 0.0f && t < t_min) {
396 if (ptn && nearest == 0) {
407 KDTreeNearest_3d *ptn =
nullptr;
409 float vec[3] = {0.0f, 0.0f, 0.0f};
410 int neighbors = BLI_kdtree_3d_range_search(
414 if (neighbors > 1 && ptn[1].dist != 0.0f) {
429 neighbors = BLI_kdtree_3d_range_search(
432 if (neighbors > 0 && ptn[0].dist <
len) {
451 KDTreeNearest_3d ptn[11];
452 float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
453 int neighbors = BLI_kdtree_3d_find_nearest_n_with_len_squared_cb(
464 for (n = 1; n < neighbors; n++) {
469 mul_v3_fl(loc, 1.0f / (
float(neighbors) - 1.0f));
470 mul_v3_fl(vec, 1.0f / (
float(neighbors) - 1.0f));
489 float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
522 if (t > 0.0f && t < 3.0f) {
558 float vec2[3], t, t_min = 3.0f;
582 if (t > 0.0f && t < t_min) {
632 float vec[3] = {0.0f, 0.0f, 0.0f};
634 if (asbr->
wander > 0.0f) {
683 KDTreeNearest_3d *ptn =
nullptr;
688 float closest_enemy[3] = {0.0f, 0.0f, 0.0f};
689 float closest_dist = fbr->
distance + 1.0f;
690 float f_strength = 0.0f, e_strength = 0.0f;
696 int neighbors = BLI_kdtree_3d_range_search(
698 for (n = 0; n < neighbors; n++) {
717 for (n = 0; n < neighbors; n++) {
718 bpa = epars[ptn[n].index].
boid;
723 closest_dist = ptn[n].dist;
724 enemy_pa = epars + ptn[n].index;
738 if (e_strength > 0.0f) {
742 if (closest_dist <= bbd->part->boids->range + pa->
size + enemy_pa->
size) {
753 bpa = enemy_pa->
boid;
767 e_strength / f_strength)
770 if (closest_dist < fbr->flee_distance * fbr->
distance) {
855 const float zvec[3] = {0.0f, 0.0f, 2000.0f};
858 float radius = 0.0f, t, ray_dir[3];
876 col.current = coll->ob;
877 col.md = coll->collmd;
878 col.fac1 =
col.fac2 = 0.0f;
880 if (
col.md &&
col.md->bvhtree) {
892 if (hit.
index >= 0) {
893 t = hit.
dist /
col.original_ray_length;
909 col.current = coll->ob;
910 col.md = coll->collmd;
912 if (
col.md &&
col.md->bvhtree) {
924 if (hit.
index >= 0) {
925 t = hit.
dist /
col.original_ray_length;
934 ground_nor[0] = ground_nor[1] = 0.0f;
935 ground_nor[2] = 1.0f;
942 if (rule ==
nullptr) {
964 if (flbr->
ob && flbr->
cfra != cfra) {
980 float nor[3], vel[3];
1007 if (rule ==
nullptr) {
1048static int boid_condition_is_true(BoidCondition *cond)
1072 BoidCondition *cond =
state->conditions.first;
1073 for (; cond; cond = cond->next) {
1074 if (boid_condition_is_true(cond)) {
1075 pa->
boid->state_id = cond->state_id;
1092 switch (
state->ruleset_type) {
1111 float wanted_co[3] = {0.0f, 0.0f, 0.0f}, wanted_speed = 0.0f;
1125 wanted_speed /=
float(n);
1137 float mul = 1.0f +
state->rule_fuzziness;
1140 float cvel[3], dir[3];
1158 float cvel[3], dir[3];
1159 float z_v, ground_v, cur_v;
1181 len =
safe_sqrtf((ground_v - cur_v) * (ground_v - cur_v) + z_v * z_v);
1217 float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
1218 float dvec[3], bvec[3];
1219 float new_dir[3], new_speed;
1220 float old_dir[3], old_speed;
1221 float wanted_dir[3];
1222 float q[4], mat[3][3];
1223 float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
1224 float force[3] = {0.0f, 0.0f, 0.0f};
1233 pa_mass *= pa->
size;
1250 float landing_level = 2.0f;
1251 float level = landing_level + 1.0f;
1274 else if (level < landing_level) {
1276 bbd->
wanted_co[2] *= (level - 1.0f) / landing_level;
1285 if (new_speed == 0.0f) {
1289 float old_dir2[2], wanted_dir2[2],
nor[3],
angle;
1297 if (
dot_v2v2(old_dir2, wanted_dir2) < -0.99f) {
1336 if (level >= landing_level) {
1337 float len2 =
dot_v2v2(new_vel, new_vel);
1341 root =
safe_sqrtf(new_speed * new_speed - len2);
1343 new_vel[2] = new_vel[2] < 0.0f ? -root : root;
1433 boid_climb(boids, pa, ground_co, ground_nor);
1469 boid_climb(boids, pa, ground_co, ground_nor);
1488 boid_climb(boids, pa, ground_co, ground_nor);
1515 boid_climb(boids, pa, ground_co, ground_nor);
1596 rule =
reinterpret_cast<BoidRule *
>(rule_goal);
1601 "BoidRuleAvoidCollision");
1603 rule =
reinterpret_cast<BoidRule *
>(rule_avoid);
1608 "BoidRuleFollowLeader");
1610 rule =
reinterpret_cast<BoidRule *
>(rule_follow);
1615 "BoidRuleAverageSpeed");
1616 rule_avgspeed->
speed = 0.5f;
1617 rule =
reinterpret_cast<BoidRule *
>(rule_avgspeed);
1654 boids->
pitch = 1.0f;
1660 boids->
range = 1.0f;
1676 state->rule_fuzziness = 0.5;
1677 state->volume = 1.0f;
1678 state->channels |= ~0;
float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights)
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
bool get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity)
bool closest_point_on_surface(struct SurfaceModifierData *surmd, const float co[3], float surface_co[3], float surface_nor[3], float surface_vel[3])
void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time)
void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit)
int psys_uses_gravity(struct ParticleSimulationData *sim)
struct ParticleSystem * psys_get_target_system(struct Object *ob, struct ParticleTarget *pt)
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
#define BVH_RAYCAST_DEFAULT
int BLI_bvhtree_ray_cast_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata, int flag)
A KD-tree for nearest neighbor search.
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
MINLINE float min_ff(float a, float b)
MINLINE float safe_sqrtf(float a)
MINLINE float safe_acosf(float a)
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void mul_qt_v3(const float q[4], float r[3])
void mat3_to_quat_legacy(float q[4], const float wmat[3][3])
void copy_qt_qt(float q[4], const float a[4])
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v2(float n[2])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define SNPRINTF_UTF8(dst, format,...)
#define STRNCPY_UTF8(dst, src)
#define ARRAY_HAS_ITEM(arr_item, arr_start, arr_len)
#define BOIDSTATE_CURRENT
#define BRULE_LEADER_IN_LINE
@ BRULE_GOAL_AVOID_PREDICT
@ eBoidRulesetType_Average
@ eBoidRulesetType_Random
@ eBoidRuleType_FollowLeader
@ eBoidRuleType_AvoidCollision
@ eBoidRuleType_AverageSpeed
@ BRULE_ACOLL_WITH_DEFLECTORS
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
void boid_free_settings(BoidSettings *boids)
bool(*)(BoidRule *rule, BoidBrainData *data, BoidValues *val, ParticleData *pa) boid_rule_cb
BoidRule * boid_new_rule(int type)
BoidSettings * boid_copy_settings(const BoidSettings *boids)
static bool rule_flock(BoidRule *, BoidBrainData *bbd, BoidValues *, ParticleData *pa)
static bool rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
BoidState * boid_get_current_state(BoidSettings *boids)
BoidState * boid_new_state(BoidSettings *boids)
static bool rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, float *surface_nor)
static bool apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val, ParticleData *pa, float fuzziness)
void boid_body(BoidBrainData *bbd, ParticleData *pa)
static bool rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
void boids_precalc_rules(ParticleSettings *part, float cfra)
static bool rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
static bool rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
static BoidState * get_boid_state(BoidSettings *boids, ParticleData *pa)
static float boid_goal_signed_dist(float *boid_co, float *goal_co, float *goal_nor)
static float len_squared_v3v3_with_normal_bias(const float co_search[3], const float co_test[3], const void *user_data)
void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
static bool boid_rule_applies(ParticleData *pa, BoidSettings *, BoidRule *rule)
BoidState * boid_duplicate_state(BoidSettings *boids, BoidState *state)
static boid_rule_cb boid_rules[]
static bool rule_separate(BoidRule *, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
static bool rule_none(BoidRule *, BoidBrainData *, BoidValues *, ParticleData *)
static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *pa)
void boid_default_settings(BoidSettings *boids)
static Object * boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float ground_co[3], float ground_nor[3])
void jump(const btVector3 &v=btVector3(0, 0, 0))
static void mul(btAlignedObjectArray< T > &items, const Q &value)
float length(VecOp< float, D >) RET
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
const EnumPropertyItem rna_enum_boidrule_type_items[]
struct ParticleSettings * part
struct ParticleSimulationData * sim
float land_personal_space
struct Depsgraph * depsgraph
struct BoidSettings * boids
struct EffectorWeights * effector_weights
struct Depsgraph * depsgraph
struct ParticleSystem * psys
struct ListBase * colliders
struct ListBase * effectors
struct PhysicsSettings physics_settings