General particle bug fixes + few small goodies
The goodies: * Curves can be used as normal dynamic effectors too with the new "curve" field shape. * Group visualization has optional duplication counts for each object in the specified group. * Object & group visualizations, which are done without taking the dupliobject's global position into account (unless the whole group is used). This is much nicer than the previous behavior, but I added a "Use Global Location" option for those who want to use it the old way. * The active particle system's particles are now drawn a with theme coloured outline instead of pure white. * Added object aligned velocity factors (buttons categorized and re-organized too). Bug fixes: * Absorption didn't work as the ui toggle button was forgotten. * Some other force field ui tweaks. * Crash after adding children and changing trails count. * Display types "cross" and "axis" crashed. * Particles weren't drawn with correct coloring. * Billboards didn't update properly in viewport to camera location changes. * Particle rotation wasn't recreated correctly from point cache. * Changing particles amount crashed sometimes. * Some files with child hair crashed on loading. * Compiler warning fixes. * Adding boids crashed on frame 1;
This commit is contained in:
@@ -121,17 +121,19 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
|
|||||||
layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
|
layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
row.active = part.distribution != 'GRID'
|
||||||
row.itemR(part, "amount")
|
row.itemR(part, "amount")
|
||||||
|
|
||||||
split = layout.split()
|
if part.type != 'HAIR':
|
||||||
|
split = layout.split()
|
||||||
col = split.column(align=True)
|
|
||||||
col.itemR(part, "start")
|
col = split.column(align=True)
|
||||||
col.itemR(part, "end")
|
col.itemR(part, "start")
|
||||||
|
col.itemR(part, "end")
|
||||||
|
|
||||||
col = split.column(align=True)
|
col = split.column(align=True)
|
||||||
col.itemR(part, "lifetime")
|
col.itemR(part, "lifetime")
|
||||||
col.itemR(part, "random_lifetime", slider=True)
|
col.itemR(part, "random_lifetime", slider=True)
|
||||||
|
|
||||||
layout.row().itemL(text="Emit From:")
|
layout.row().itemL(text="Emit From:")
|
||||||
|
|
||||||
@@ -221,7 +223,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
|
|||||||
|
|
||||||
point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
|
point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
|
||||||
|
|
||||||
class PARTICLE_PT_initial(ParticleButtonsPanel):
|
class PARTICLE_PT_velocity(ParticleButtonsPanel):
|
||||||
__label__ = "Velocity"
|
__label__ = "Velocity"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
@@ -238,48 +240,66 @@ class PARTICLE_PT_initial(ParticleButtonsPanel):
|
|||||||
part = psys.settings
|
part = psys.settings
|
||||||
|
|
||||||
layout.enabled = particle_panel_enabled(psys)
|
layout.enabled = particle_panel_enabled(psys)
|
||||||
|
|
||||||
layout.row().itemL(text="Direction:")
|
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
sub = split.column()
|
sub = split.column()
|
||||||
|
sub.itemL(text="Emitter Geometry:")
|
||||||
sub.itemR(part, "normal_factor")
|
sub.itemR(part, "normal_factor")
|
||||||
|
subsub = sub.column(align=True)
|
||||||
|
subsub.itemR(part, "tangent_factor")
|
||||||
|
subsub.itemR(part, "tangent_phase", slider=True)
|
||||||
|
|
||||||
|
sub = split.column()
|
||||||
|
sub.itemL(text="Emitter Object")
|
||||||
|
sub.itemR(part, "object_aligned_factor", text="")
|
||||||
|
|
||||||
|
layout.row().itemL(text="Other:")
|
||||||
|
split = layout.split()
|
||||||
|
sub = split.column()
|
||||||
if part.emit_from=='PARTICLE':
|
if part.emit_from=='PARTICLE':
|
||||||
sub.itemR(part, "particle_factor")
|
sub.itemR(part, "particle_factor")
|
||||||
else:
|
else:
|
||||||
sub.itemR(part, "object_factor", slider=True)
|
sub.itemR(part, "object_factor", slider=True)
|
||||||
|
sub = split.column()
|
||||||
sub.itemR(part, "random_factor")
|
sub.itemR(part, "random_factor")
|
||||||
sub.itemR(part, "tangent_factor")
|
|
||||||
sub.itemR(part, "tangent_phase", slider=True)
|
|
||||||
|
|
||||||
sub = split.column()
|
#if part.type=='REACTOR':
|
||||||
sub.itemL(text="TODO:")
|
# sub.itemR(part, "reactor_factor")
|
||||||
sub.itemL(text="Object aligned")
|
# sub.itemR(part, "reaction_shape", slider=True)
|
||||||
sub.itemL(text="direction: X, Y, Z")
|
|
||||||
|
|
||||||
if part.type=='REACTOR':
|
class PARTICLE_PT_rotation(ParticleButtonsPanel):
|
||||||
sub.itemR(part, "reactor_factor")
|
__label__ = "Rotation"
|
||||||
sub.itemR(part, "reaction_shape", slider=True)
|
|
||||||
|
def poll(self, context):
|
||||||
|
if particle_panel_poll(context):
|
||||||
|
psys = context.particle_system
|
||||||
|
return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
|
||||||
else:
|
else:
|
||||||
sub.itemL(text="")
|
return False
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
psys = context.particle_system
|
||||||
|
part = psys.settings
|
||||||
|
|
||||||
layout.row().itemL(text="Rotation:")
|
layout.enabled = particle_panel_enabled(psys)
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
split.itemL(text="Initial Rotation:")
|
||||||
|
split.itemR(part, "rotation_dynamic")
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
sub = split.column()
|
sub = split.column(align=True)
|
||||||
|
sub.itemR(part, "rotation_mode", text="")
|
||||||
sub.itemR(part, "rotation_mode", text="Axis")
|
sub.itemR(part, "random_rotation_factor", slider=True, text="Random")
|
||||||
split = layout.split()
|
|
||||||
|
|
||||||
sub = split.column()
|
sub = split.column(align=True)
|
||||||
sub.itemR(part, "rotation_dynamic")
|
|
||||||
sub.itemR(part, "random_rotation_factor", slider=True)
|
|
||||||
sub = split.column()
|
|
||||||
sub.itemR(part, "phase_factor", slider=True)
|
sub.itemR(part, "phase_factor", slider=True)
|
||||||
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
|
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
|
||||||
|
|
||||||
layout.row().itemL(text="Angular velocity:")
|
layout.row().itemL(text="Angular Velocity:")
|
||||||
layout.row().itemR(part, "angular_velocity_mode", expand=True)
|
layout.row().itemR(part, "angular_velocity_mode", expand=True)
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
@@ -607,16 +627,37 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
|
|||||||
|
|
||||||
elif part.ren_as == 'OBJECT':
|
elif part.ren_as == 'OBJECT':
|
||||||
sub.itemR(part, "dupli_object")
|
sub.itemR(part, "dupli_object")
|
||||||
|
sub.itemR(part, "use_global_dupli")
|
||||||
elif part.ren_as == 'GROUP':
|
elif part.ren_as == 'GROUP':
|
||||||
sub.itemR(part, "dupli_group")
|
sub.itemR(part, "dupli_group")
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
sub = split.column()
|
sub = split.column()
|
||||||
sub.itemR(part, "whole_group")
|
sub.itemR(part, "whole_group")
|
||||||
|
colsub = sub.column()
|
||||||
|
colsub.active = part.whole_group == False
|
||||||
|
colsub.itemR(part, "use_group_count")
|
||||||
|
|
||||||
sub = split.column()
|
sub = split.column()
|
||||||
colsub = sub.column()
|
colsub = sub.column()
|
||||||
colsub.active = part.whole_group == False
|
colsub.active = part.whole_group == False
|
||||||
|
colsub.itemR(part, "use_global_dupli")
|
||||||
colsub.itemR(part, "rand_group")
|
colsub.itemR(part, "rand_group")
|
||||||
|
|
||||||
|
if part.use_group_count and not part.whole_group:
|
||||||
|
row = layout.row()
|
||||||
|
row.template_list(part, "dupliweights", part, "active_dupliweight_index")
|
||||||
|
|
||||||
|
col = row.column()
|
||||||
|
subrow = col.row()
|
||||||
|
subcol = subrow.column(align=True)
|
||||||
|
subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="")
|
||||||
|
subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||||
|
|
||||||
|
weight = part.active_dupliweight
|
||||||
|
if weight:
|
||||||
|
row = layout.row()
|
||||||
|
row.itemR(weight, "count")
|
||||||
|
|
||||||
elif part.ren_as == 'BILLBOARD':
|
elif part.ren_as == 'BILLBOARD':
|
||||||
sub.itemL(text="Align:")
|
sub.itemL(text="Align:")
|
||||||
|
|
||||||
@@ -898,7 +939,8 @@ bpy.types.register(PARTICLE_PT_particles)
|
|||||||
bpy.types.register(PARTICLE_PT_hair_dynamics)
|
bpy.types.register(PARTICLE_PT_hair_dynamics)
|
||||||
bpy.types.register(PARTICLE_PT_cache)
|
bpy.types.register(PARTICLE_PT_cache)
|
||||||
bpy.types.register(PARTICLE_PT_emission)
|
bpy.types.register(PARTICLE_PT_emission)
|
||||||
bpy.types.register(PARTICLE_PT_initial)
|
bpy.types.register(PARTICLE_PT_velocity)
|
||||||
|
bpy.types.register(PARTICLE_PT_rotation)
|
||||||
bpy.types.register(PARTICLE_PT_physics)
|
bpy.types.register(PARTICLE_PT_physics)
|
||||||
bpy.types.register(PARTICLE_PT_boidbrain)
|
bpy.types.register(PARTICLE_PT_boidbrain)
|
||||||
bpy.types.register(PARTICLE_PT_render)
|
bpy.types.register(PARTICLE_PT_render)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def effector_weights_ui(self, weights):
|
|||||||
layout.itemS()
|
layout.itemS()
|
||||||
|
|
||||||
flow = layout.column_flow()
|
flow = layout.column_flow()
|
||||||
flow.itemR(weights, "spherical", slider=True)
|
flow.itemR(weights, "force", slider=True)
|
||||||
flow.itemR(weights, "vortex", slider=True)
|
flow.itemR(weights, "vortex", slider=True)
|
||||||
flow.itemR(weights, "magnetic", slider=True)
|
flow.itemR(weights, "magnetic", slider=True)
|
||||||
flow.itemR(weights, "wind", slider=True)
|
flow.itemR(weights, "wind", slider=True)
|
||||||
@@ -110,7 +110,7 @@ def basic_force_field_settings_ui(self, field):
|
|||||||
col.itemR(field, "flow")
|
col.itemR(field, "flow")
|
||||||
elif field.type == 'HARMONIC':
|
elif field.type == 'HARMONIC':
|
||||||
col.itemR(field, "harmonic_damping", text="Damping")
|
col.itemR(field, "harmonic_damping", text="Damping")
|
||||||
elif field.type == 'VORTEX' and field.shape == 'PLANE':
|
elif field.type == 'VORTEX' and field.shape != 'POINT':
|
||||||
col.itemR(field, "inflow")
|
col.itemR(field, "inflow")
|
||||||
elif field.type == 'DRAG':
|
elif field.type == 'DRAG':
|
||||||
col.itemR(field, "quadratic_drag", text="Quadratic")
|
col.itemR(field, "quadratic_drag", text="Quadratic")
|
||||||
@@ -140,6 +140,7 @@ def basic_force_field_falloff_ui(self, field):
|
|||||||
col.itemR(field, "z_direction", text="")
|
col.itemR(field, "z_direction", text="")
|
||||||
col.itemR(field, "use_min_distance", text="Use Minimum")
|
col.itemR(field, "use_min_distance", text="Use Minimum")
|
||||||
col.itemR(field, "use_max_distance", text="Use Maximum")
|
col.itemR(field, "use_max_distance", text="Use Maximum")
|
||||||
|
col.itemR(field, "do_absorption")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.itemR(field, "falloff_power", text="Power")
|
col.itemR(field, "falloff_power", text="Power")
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ typedef struct BVHTreeFromMesh
|
|||||||
|
|
||||||
/* Vertex array, so that callbacks have instante access to data */
|
/* Vertex array, so that callbacks have instante access to data */
|
||||||
struct MVert *vert;
|
struct MVert *vert;
|
||||||
|
struct MEdge *edge; /* only used for BVHTreeFromMeshEdges */
|
||||||
struct MFace *face;
|
struct MFace *face;
|
||||||
|
|
||||||
/* radius for raycast */
|
/* radius for raycast */
|
||||||
@@ -96,6 +97,8 @@ BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMes
|
|||||||
*/
|
*/
|
||||||
BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
|
BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
|
||||||
|
|
||||||
|
BVHTree* bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees data allocated by a call to bvhtree_from_mesh_*.
|
* Frees data allocated by a call to bvhtree_from_mesh_*.
|
||||||
*/
|
*/
|
||||||
@@ -109,6 +112,7 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data);
|
|||||||
//Using local coordinates
|
//Using local coordinates
|
||||||
#define BVHTREE_FROM_FACES 0
|
#define BVHTREE_FROM_FACES 0
|
||||||
#define BVHTREE_FROM_VERTICES 1
|
#define BVHTREE_FROM_VERTICES 1
|
||||||
|
#define BVHTREE_FROM_EDGES 2
|
||||||
|
|
||||||
typedef LinkNode* BVHCache;
|
typedef LinkNode* BVHCache;
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struc
|
|||||||
/* EffectedPoint->flag */
|
/* EffectedPoint->flag */
|
||||||
#define PE_WIND_AS_SPEED 1
|
#define PE_WIND_AS_SPEED 1
|
||||||
#define PE_DYNAMIC_ROTATION 2
|
#define PE_DYNAMIC_ROTATION 2
|
||||||
|
#define PE_USE_NORMAL_DATA 4
|
||||||
|
|
||||||
/* EffectorData->flag */
|
/* EffectorData->flag */
|
||||||
#define PE_VELOCITY_TO_IMPULSE 1
|
#define PE_VELOCITY_TO_IMPULSE 1
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ struct Object *psys_get_lattice(struct ParticleSimulationData *sim);
|
|||||||
int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
|
int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
|
||||||
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
|
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
|
||||||
|
|
||||||
|
void psys_check_group_weights(struct ParticleSettings *part);
|
||||||
|
|
||||||
/* free */
|
/* free */
|
||||||
void psys_free_settings(struct ParticleSettings *part);
|
void psys_free_settings(struct ParticleSettings *part);
|
||||||
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||||
|
|||||||
@@ -776,6 +776,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
GroupObject *go;
|
GroupObject *go;
|
||||||
Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
|
Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
|
||||||
DupliObject *dob;
|
DupliObject *dob;
|
||||||
|
ParticleDupliWeight *dw;
|
||||||
ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)};
|
ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)};
|
||||||
ParticleSettings *part;
|
ParticleSettings *part;
|
||||||
ParticleData *pa;
|
ParticleData *pa;
|
||||||
@@ -783,7 +784,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
ParticleKey state;
|
ParticleKey state;
|
||||||
ParticleCacheKey *cache;
|
ParticleCacheKey *cache;
|
||||||
float ctime, pa_time, scale = 1.0f;
|
float ctime, pa_time, scale = 1.0f;
|
||||||
float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
|
float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0;
|
||||||
float (*obmat)[4], (*oldobmat)[4];
|
float (*obmat)[4], (*oldobmat)[4];
|
||||||
int lay, a, b, counter, hair = 0;
|
int lay, a, b, counter, hair = 0;
|
||||||
int totpart, totchild, totgroup=0, pa_num;
|
int totpart, totchild, totgroup=0, pa_num;
|
||||||
@@ -813,6 +814,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
|
((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
|
||||||
(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
|
(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
|
||||||
|
|
||||||
|
psys_check_group_weights(part);
|
||||||
|
|
||||||
/* if we have a hair particle system, use the path cache */
|
/* if we have a hair particle system, use the path cache */
|
||||||
if(part->type == PART_HAIR) {
|
if(part->type == PART_HAIR) {
|
||||||
if(psys->flag & PSYS_HAIR_DONE)
|
if(psys->flag & PSYS_HAIR_DONE)
|
||||||
@@ -831,18 +834,37 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
if(part->ren_as==PART_DRAW_GR) {
|
if(part->ren_as==PART_DRAW_GR) {
|
||||||
group_handle_recalc_and_update(scene, par, part->dup_group);
|
group_handle_recalc_and_update(scene, par, part->dup_group);
|
||||||
|
|
||||||
for(go=part->dup_group->gobject.first; go; go=go->next)
|
if(part->draw & PART_DRAW_COUNT_GR) {
|
||||||
totgroup++;
|
for(dw=part->dupliweights.first; dw; dw=dw->next)
|
||||||
|
totgroup += dw->count;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(go=part->dup_group->gobject.first; go; go=go->next)
|
||||||
|
totgroup++;
|
||||||
|
}
|
||||||
|
|
||||||
/* we also copy the actual objects to restore afterwards, since
|
/* we also copy the actual objects to restore afterwards, since
|
||||||
* where_is_object_time will change the object which breaks transform */
|
* where_is_object_time will change the object which breaks transform */
|
||||||
oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
|
oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
|
||||||
obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list");
|
obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list");
|
||||||
|
|
||||||
go = part->dup_group->gobject.first;
|
|
||||||
for(a=0; a<totgroup; a++, go=go->next) {
|
if(part->draw & PART_DRAW_COUNT_GR && totgroup) {
|
||||||
oblist[a] = go->ob;
|
dw = part->dupliweights.first;
|
||||||
obcopylist[a] = *go->ob;
|
|
||||||
|
for(a=0; a<totgroup; dw=dw->next) {
|
||||||
|
for(b=0; b<dw->count; b++, a++) {
|
||||||
|
oblist[a] = dw->ob;
|
||||||
|
obcopylist[a] = *dw->ob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go = part->dup_group->gobject.first;
|
||||||
|
for(a=0; a<totgroup; a++, go=go->next) {
|
||||||
|
oblist[a] = go->ob;
|
||||||
|
obcopylist[a] = *go->ob;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -936,11 +958,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
else {
|
else {
|
||||||
/* to give ipos in object correct offset */
|
/* to give ipos in object correct offset */
|
||||||
where_is_object_time(scene, ob, ctime-pa_time);
|
where_is_object_time(scene, ob, ctime-pa_time);
|
||||||
|
|
||||||
|
VECCOPY(vec, obmat[3]);
|
||||||
|
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
|
||||||
|
|
||||||
Mat4CpyMat4(mat, pamat);
|
Mat4CpyMat4(mat, pamat);
|
||||||
|
|
||||||
Mat4MulMat4(tmat, obmat, mat);
|
Mat4MulMat4(tmat, obmat, mat);
|
||||||
Mat4MulFloat3((float *)tmat, size*scale);
|
Mat4MulFloat3((float *)tmat, size*scale);
|
||||||
|
|
||||||
|
if(part->draw & PART_DRAW_GLOBAL_OB)
|
||||||
|
VECADD(tmat[3], tmat[3], vec);
|
||||||
|
|
||||||
if(par_space_mat)
|
if(par_space_mat)
|
||||||
Mat4MulMat4(mat, tmat, par_space_mat);
|
Mat4MulMat4(mat, tmat, par_space_mat);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -73,13 +73,11 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
|||||||
{
|
{
|
||||||
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
|
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
|
||||||
BoidSettings *boids = bbd->part->boids;
|
BoidSettings *boids = bbd->part->boids;
|
||||||
Object *priority_ob = NULL;
|
|
||||||
BoidParticle *bpa = pa->boid;
|
BoidParticle *bpa = pa->boid;
|
||||||
EffectedPoint epoint;
|
EffectedPoint epoint;
|
||||||
ListBase *effectors = bbd->sim->psys->effectors;
|
ListBase *effectors = bbd->sim->psys->effectors;
|
||||||
EffectorCache *cur, *eff = NULL;
|
EffectorCache *cur, *eff = NULL;
|
||||||
EffectorData efd, cur_efd;
|
EffectorData efd, cur_efd;
|
||||||
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
|
|
||||||
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
|
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
|
||||||
float priority = 0.0f, len = 0.0f;
|
float priority = 0.0f, len = 0.0f;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -1051,9 +1049,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
|
|||||||
float wanted_dir[3];
|
float wanted_dir[3];
|
||||||
float q[4], mat[3][3]; /* rotation */
|
float q[4], mat[3][3]; /* rotation */
|
||||||
float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
|
float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
|
||||||
float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f};
|
float force[3] = {0.0f, 0.0f, 0.0f};
|
||||||
float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
|
float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
|
||||||
int p = pa - bbd->sim->psys->particles;
|
|
||||||
|
|
||||||
set_boid_values(&val, boids, pa);
|
set_boid_values(&val, boids, pa);
|
||||||
|
|
||||||
|
|||||||
@@ -479,6 +479,32 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r
|
|||||||
} while(t2);
|
} while(t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges.
|
||||||
|
// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
|
||||||
|
static void mesh_edges_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
|
||||||
|
{
|
||||||
|
const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
|
||||||
|
MVert *vert = data->vert;
|
||||||
|
MEdge *edge = data->edge + index;
|
||||||
|
float nearest_tmp[3], dist;
|
||||||
|
|
||||||
|
float *t0, *t1;
|
||||||
|
t0 = vert[ edge->v1 ].co;
|
||||||
|
t1 = vert[ edge->v2 ].co;
|
||||||
|
|
||||||
|
PclosestVL3Dfl(nearest_tmp, co, t0, t1);
|
||||||
|
dist = VecLenf(nearest_tmp, co);
|
||||||
|
|
||||||
|
if(dist < nearest->dist)
|
||||||
|
{
|
||||||
|
nearest->index = index;
|
||||||
|
nearest->dist = dist;
|
||||||
|
VECCOPY(nearest->co, nearest_tmp);
|
||||||
|
VecSubf(nearest->no, t0, t1);
|
||||||
|
Normalize(nearest->no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BVH builders
|
* BVH builders
|
||||||
*/
|
*/
|
||||||
@@ -605,6 +631,68 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Builds a bvh tree.. where nodes are the faces of the given mesh.
|
||||||
|
BVHTree* bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
|
||||||
|
{
|
||||||
|
BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_EDGES);
|
||||||
|
|
||||||
|
//Not in cache
|
||||||
|
if(tree == NULL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int numEdges= mesh->getNumEdges(mesh);
|
||||||
|
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
|
||||||
|
MEdge *edge = mesh->getEdgeDataArray(mesh, CD_MEDGE);
|
||||||
|
|
||||||
|
if(vert != NULL && edge != NULL)
|
||||||
|
{
|
||||||
|
/* Create a bvh-tree of the given target */
|
||||||
|
tree = BLI_bvhtree_new(numEdges, epsilon, tree_type, axis);
|
||||||
|
if(tree != NULL)
|
||||||
|
{
|
||||||
|
for(i = 0; i < numEdges; i++)
|
||||||
|
{
|
||||||
|
float co[4][3];
|
||||||
|
VECCOPY(co[0], vert[ edge[i].v1 ].co);
|
||||||
|
VECCOPY(co[1], vert[ edge[i].v2 ].co);
|
||||||
|
|
||||||
|
BLI_bvhtree_insert(tree, i, co[0], 2);
|
||||||
|
}
|
||||||
|
BLI_bvhtree_balance(tree);
|
||||||
|
|
||||||
|
//Save on cache for later use
|
||||||
|
// printf("BVHTree built and saved on cache\n");
|
||||||
|
bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_EDGES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// printf("BVHTree is already build, using cached tree\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Setup BVHTreeFromMesh
|
||||||
|
memset(data, 0, sizeof(*data));
|
||||||
|
data->tree = tree;
|
||||||
|
|
||||||
|
if(data->tree)
|
||||||
|
{
|
||||||
|
data->cached = TRUE;
|
||||||
|
|
||||||
|
data->nearest_callback = mesh_edges_nearest_point;
|
||||||
|
data->raycast_callback = NULL;
|
||||||
|
|
||||||
|
data->mesh = mesh;
|
||||||
|
data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
|
||||||
|
data->edge = mesh->getEdgeDataArray(mesh, CD_MEDGE);
|
||||||
|
|
||||||
|
data->sphere_radius = epsilon;
|
||||||
|
}
|
||||||
|
return data->tree;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Frees data allocated by a call to bvhtree_from_mesh_*.
|
// Frees data allocated by a call to bvhtree_from_mesh_*.
|
||||||
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
|
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -228,6 +228,8 @@ static void precalculate_effector(EffectorCache *eff)
|
|||||||
}
|
}
|
||||||
else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) {
|
else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) {
|
||||||
eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface );
|
eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface );
|
||||||
|
if(eff->ob->type == OB_CURVE)
|
||||||
|
eff->flag |= PE_USE_NORMAL_DATA;
|
||||||
}
|
}
|
||||||
else if(eff->psys)
|
else if(eff->psys)
|
||||||
psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
|
psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
|
||||||
@@ -518,7 +520,7 @@ float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *poi
|
|||||||
float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f;
|
float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f;
|
||||||
float fac, r_fac;
|
float fac, r_fac;
|
||||||
|
|
||||||
fac = Inpf(efd->nor, efd->vec_to_point);
|
fac = Inpf(efd->nor, efd->vec_to_point2);
|
||||||
|
|
||||||
if(eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f)
|
if(eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f)
|
||||||
falloff=0.0f;
|
falloff=0.0f;
|
||||||
@@ -691,10 +693,16 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
|
|||||||
VecSubf(efd->vec_to_point, point->loc, efd->loc);
|
VecSubf(efd->vec_to_point, point->loc, efd->loc);
|
||||||
efd->distance = VecLength(efd->vec_to_point);
|
efd->distance = VecLength(efd->vec_to_point);
|
||||||
|
|
||||||
/* for some effectors we need the object center every time */
|
if(eff->flag & PE_USE_NORMAL_DATA) {
|
||||||
VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]);
|
VECCOPY(efd->vec_to_point2, efd->vec_to_point);
|
||||||
VECCOPY(efd->nor2, eff->ob->obmat[2]);
|
VECCOPY(efd->nor2, efd->nor);
|
||||||
Normalize(efd->nor2);
|
}
|
||||||
|
else {
|
||||||
|
/* for some effectors we need the object center every time */
|
||||||
|
VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]);
|
||||||
|
VECCOPY(efd->nor2, eff->ob->obmat[2]);
|
||||||
|
Normalize(efd->nor2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -835,8 +843,7 @@ void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *
|
|||||||
|
|
||||||
switch(pd->forcefield){
|
switch(pd->forcefield){
|
||||||
case PFIELD_WIND:
|
case PFIELD_WIND:
|
||||||
Normalize(force);
|
VECCOPY(force, efd->nor);
|
||||||
strength *= (Inpf(force, efd->nor) >= 0.0f ? 1.0f : -1.0f);
|
|
||||||
VecMulf(force, strength * efd->falloff);
|
VecMulf(force, strength * efd->falloff);
|
||||||
break;
|
break;
|
||||||
case PFIELD_FORCE:
|
case PFIELD_FORCE:
|
||||||
|
|||||||
@@ -6211,7 +6211,8 @@ static void surfaceModifier_freeData(ModifierData *md)
|
|||||||
MEM_freeN(surmd->bvhtree);
|
MEM_freeN(surmd->bvhtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
surmd->dm->release(surmd->dm);
|
if(surmd->dm)
|
||||||
|
surmd->dm->release(surmd->dm);
|
||||||
|
|
||||||
if(surmd->x)
|
if(surmd->x)
|
||||||
MEM_freeN(surmd->x);
|
MEM_freeN(surmd->x);
|
||||||
@@ -6298,7 +6299,10 @@ static void surfaceModifier_deformVerts(
|
|||||||
else
|
else
|
||||||
surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
|
surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
|
||||||
|
|
||||||
bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
|
if(surmd->dm->getNumFaces(surmd->dm))
|
||||||
|
bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
|
||||||
|
else
|
||||||
|
bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_boid_types.h"
|
#include "DNA_boid_types.h"
|
||||||
|
#include "DNA_group_types.h"
|
||||||
#include "DNA_particle_types.h"
|
#include "DNA_particle_types.h"
|
||||||
#include "DNA_mesh_types.h"
|
#include "DNA_mesh_types.h"
|
||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
#include "BKE_cloth.h"
|
#include "BKE_cloth.h"
|
||||||
#include "BKE_effect.h"
|
#include "BKE_effect.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_group.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_lattice.h"
|
#include "BKE_lattice.h"
|
||||||
#include "BKE_utildefines.h"
|
#include "BKE_utildefines.h"
|
||||||
@@ -296,6 +298,60 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void psys_check_group_weights(ParticleSettings *part)
|
||||||
|
{
|
||||||
|
ParticleDupliWeight *dw, *tdw;
|
||||||
|
GroupObject *go;
|
||||||
|
int current = 0;
|
||||||
|
|
||||||
|
if(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first) {
|
||||||
|
/* first remove all weights that don't have an object in the group */
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
while(dw) {
|
||||||
|
if(!object_in_group(dw->ob, part->dup_group)) {
|
||||||
|
tdw = dw->next;
|
||||||
|
BLI_freelinkN(&part->dupliweights, dw);
|
||||||
|
dw = tdw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dw = dw->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then add objects in the group to new list */
|
||||||
|
go = part->dup_group->gobject.first;
|
||||||
|
while(go) {
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
while(dw && dw->ob != go->ob)
|
||||||
|
dw = dw->next;
|
||||||
|
|
||||||
|
if(!dw) {
|
||||||
|
dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight");
|
||||||
|
dw->ob = go->ob;
|
||||||
|
dw->count = 1;
|
||||||
|
BLI_addtail(&part->dupliweights, dw);
|
||||||
|
}
|
||||||
|
|
||||||
|
go = go->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
for(; dw; dw=dw->next) {
|
||||||
|
if(dw->flag & PART_DUPLIW_CURRENT) {
|
||||||
|
current = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!current) {
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
if(dw)
|
||||||
|
dw->flag |= PART_DUPLIW_CURRENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_freelistN(&part->dupliweights);
|
||||||
|
}
|
||||||
|
}
|
||||||
/************************************************/
|
/************************************************/
|
||||||
/* Freeing stuff */
|
/* Freeing stuff */
|
||||||
/************************************************/
|
/************************************************/
|
||||||
@@ -307,6 +363,8 @@ void psys_free_settings(ParticleSettings *part)
|
|||||||
if(part->effector_weights)
|
if(part->effector_weights)
|
||||||
MEM_freeN(part->effector_weights);
|
MEM_freeN(part->effector_weights);
|
||||||
|
|
||||||
|
BLI_freelistN(&part->dupliweights);
|
||||||
|
|
||||||
boid_free_settings(part->boids);
|
boid_free_settings(part->boids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,6 +497,9 @@ void psys_free_pdd(ParticleSystem *psys)
|
|||||||
if(psys->pdd->vedata)
|
if(psys->pdd->vedata)
|
||||||
MEM_freeN(psys->pdd->vedata);
|
MEM_freeN(psys->pdd->vedata);
|
||||||
psys->pdd->vedata = NULL;
|
psys->pdd->vedata = NULL;
|
||||||
|
|
||||||
|
psys->pdd->totpoint = 0;
|
||||||
|
psys->pdd->tot_vec_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free everything */
|
/* free everything */
|
||||||
@@ -2047,10 +2108,10 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
|
|||||||
float roughfac;
|
float roughfac;
|
||||||
|
|
||||||
roughfac=fac*(float)pow((double)t,shape);
|
roughfac=fac*(float)pow((double)t,shape);
|
||||||
VECCOPY(rough,loc);
|
Vec2Copyf(rough,loc);
|
||||||
rough[0]=-1.0f+2.0f*rough[0];
|
rough[0]=-1.0f+2.0f*rough[0];
|
||||||
rough[1]=-1.0f+2.0f*rough[1];
|
rough[1]=-1.0f+2.0f*rough[1];
|
||||||
VecMulf(rough,roughfac);
|
Vec2Mulf(rough,roughfac);
|
||||||
|
|
||||||
VECADDFAC(state->co,state->co,mat[0],rough[0]);
|
VECADDFAC(state->co,state->co,mat[0],rough[0]);
|
||||||
VECADDFAC(state->co,state->co,mat[1],rough[1]);
|
VECADDFAC(state->co,state->co,mat[1],rough[1]);
|
||||||
@@ -3235,6 +3296,9 @@ static void default_particle_settings(ParticleSettings *part)
|
|||||||
part->size=0.05;
|
part->size=0.05;
|
||||||
part->childsize=1.0;
|
part->childsize=1.0;
|
||||||
|
|
||||||
|
part->rotmode = PART_ROT_VEL;
|
||||||
|
part->avemode = PART_AVE_SPIN;
|
||||||
|
|
||||||
part->child_nbr=10;
|
part->child_nbr=10;
|
||||||
part->ren_child_nbr=100;
|
part->ren_child_nbr=100;
|
||||||
part->childrad=0.2f;
|
part->childrad=0.2f;
|
||||||
@@ -3788,6 +3852,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
|
|||||||
|
|
||||||
/* get different child parameters from textures & vgroups */
|
/* get different child parameters from textures & vgroups */
|
||||||
memset(&ctx, 0, sizeof(ParticleThreadContext));
|
memset(&ctx, 0, sizeof(ParticleThreadContext));
|
||||||
|
ctx.sim = *sim;
|
||||||
ctx.dm = psmd->dm;
|
ctx.dm = psmd->dm;
|
||||||
ctx.ma = ma;
|
ctx.ma = ma;
|
||||||
/* TODO: assign vertex groups */
|
/* TODO: assign vertex groups */
|
||||||
@@ -3856,6 +3921,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
|
|||||||
ChildParticle *cpa = NULL;
|
ChildParticle *cpa = NULL;
|
||||||
float cfra;
|
float cfra;
|
||||||
int totpart = psys->totpart;
|
int totpart = psys->totpart;
|
||||||
|
float timestep = psys_get_timestep(sim);
|
||||||
|
|
||||||
/* negative time means "use current time" */
|
/* negative time means "use current time" */
|
||||||
cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0);
|
cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0);
|
||||||
@@ -3924,13 +3990,14 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
|
|||||||
calc_latt_deform(sim->psys->lattice, state->co,1.0f);
|
calc_latt_deform(sim->psys->lattice, state->co,1.0f);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED))
|
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
|
||||||
|
|| pa->prev_state.time <= 0.0f)
|
||||||
copy_particle_key(state, &pa->state, 1);
|
copy_particle_key(state, &pa->state, 1);
|
||||||
else if(pa->prev_state.time==state->time)
|
else if(pa->prev_state.time==state->time)
|
||||||
copy_particle_key(state, &pa->prev_state, 1);
|
copy_particle_key(state, &pa->prev_state, 1);
|
||||||
else {
|
else {
|
||||||
/* let's interpolate to try to be as accurate as possible */
|
/* let's interpolate to try to be as accurate as possible */
|
||||||
if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) {
|
if(pa->state.time + 2.0f > state->time && pa->prev_state.time - 2.0f < state->time) {
|
||||||
ParticleKey keys[4];
|
ParticleKey keys[4];
|
||||||
float dfra, keytime, frs_sec = sim->scene->r.frs_sec;
|
float dfra, keytime, frs_sec = sim->scene->r.frs_sec;
|
||||||
|
|
||||||
@@ -3949,13 +4016,13 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
|
|||||||
keytime = (state->time - keys[1].time) / dfra;
|
keytime = (state->time - keys[1].time) / dfra;
|
||||||
|
|
||||||
/* convert velocity to timestep size */
|
/* convert velocity to timestep size */
|
||||||
VecMulf(keys[1].vel, dfra / frs_sec);
|
VecMulf(keys[1].vel, dfra * timestep);
|
||||||
VecMulf(keys[2].vel, dfra / frs_sec);
|
VecMulf(keys[2].vel, dfra * timestep);
|
||||||
|
|
||||||
psys_interpolate_particle(-1, keys, keytime, state, 1);
|
psys_interpolate_particle(-1, keys, keytime, state, 1);
|
||||||
|
|
||||||
/* convert back to real velocity */
|
/* convert back to real velocity */
|
||||||
VecMulf(state->vel, frs_sec / dfra);
|
VecMulf(state->vel, 1.0f / (dfra * timestep));
|
||||||
|
|
||||||
VecLerpf(state->ave, keys[1].ave, keys[2].ave, keytime);
|
VecLerpf(state->ave, keys[1].ave, keys[2].ave, keytime);
|
||||||
QuatInterpol(state->rot, keys[1].rot, keys[2].rot, keytime);
|
QuatInterpol(state->rot, keys[1].rot, keys[2].rot, keytime);
|
||||||
|
|||||||
@@ -183,6 +183,8 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
|
|||||||
|
|
||||||
if(totpart && totpart != psys->totpart) {
|
if(totpart && totpart != psys->totpart) {
|
||||||
newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
|
newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
|
||||||
|
if(psys->part->phystype == PART_PHYS_BOIDS)
|
||||||
|
newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles");
|
||||||
|
|
||||||
if(psys->particles) {
|
if(psys->particles) {
|
||||||
totsaved=MIN2(psys->totpart,totpart);
|
totsaved=MIN2(psys->totpart,totpart);
|
||||||
@@ -215,13 +217,12 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
psys->particles=newpars;
|
psys->particles=newpars;
|
||||||
|
psys->totpart=totpart;
|
||||||
|
|
||||||
if(newboids) {
|
if(newboids) {
|
||||||
LOOP_PARTICLES
|
LOOP_PARTICLES
|
||||||
pa->boid = newboids++;
|
pa->boid = newboids++;
|
||||||
}
|
}
|
||||||
|
|
||||||
psys->totpart=totpart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(psys->child) {
|
if(psys->child) {
|
||||||
@@ -1660,7 +1661,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
ParticleKey state;
|
ParticleKey state;
|
||||||
//IpoCurve *icu=0; // XXX old animation system
|
//IpoCurve *icu=0; // XXX old animation system
|
||||||
float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
|
float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
|
||||||
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
|
float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0};
|
||||||
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
|
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
|
||||||
float q_phase[4], r_phase;
|
float q_phase[4], r_phase;
|
||||||
int p = pa - psys->particles;
|
int p = pa - psys->particles;
|
||||||
@@ -1773,7 +1774,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(part->phystype==PART_PHYS_BOIDS) {
|
if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
|
||||||
BoidParticle *bpa = pa->boid;
|
BoidParticle *bpa = pa->boid;
|
||||||
float dvec[3], q[4], mat[3][3];
|
float dvec[3], q[4], mat[3][3];
|
||||||
|
|
||||||
@@ -1839,6 +1840,23 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
VECADDFAC(vel,vel,vtan,part->tanfac);
|
VECADDFAC(vel,vel,vtan,part->tanfac);
|
||||||
//VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
|
//VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
|
||||||
|
|
||||||
|
/* *emitter object orientation */
|
||||||
|
if(part->ob_vel[0]!=0.0) {
|
||||||
|
VECCOPY(vec, ob->obmat[0]);
|
||||||
|
Normalize(vec);
|
||||||
|
VECADDFAC(vel, vel, vec, part->ob_vel[0]);
|
||||||
|
}
|
||||||
|
if(part->ob_vel[1]!=0.0) {
|
||||||
|
VECCOPY(vec, ob->obmat[1]);
|
||||||
|
Normalize(vec);
|
||||||
|
VECADDFAC(vel, vel, vec, part->ob_vel[1]);
|
||||||
|
}
|
||||||
|
if(part->ob_vel[2]!=0.0) {
|
||||||
|
VECCOPY(vec, ob->obmat[2]);
|
||||||
|
Normalize(vec);
|
||||||
|
VECADDFAC(vel, vel, vec, part->ob_vel[2]);
|
||||||
|
}
|
||||||
|
|
||||||
/* *texture */
|
/* *texture */
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
|
||||||
@@ -3135,7 +3153,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
|||||||
ParticleSystem *psys = sim->psys;
|
ParticleSystem *psys = sim->psys;
|
||||||
ParticleSettings *part=psys->part;
|
ParticleSettings *part=psys->part;
|
||||||
KDTree *tree=0;
|
KDTree *tree=0;
|
||||||
//IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
//IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||||
/* Material *ma=give_current_material(sim->ob, part->omat); */
|
/* Material *ma=give_current_material(sim->ob, part->omat); */
|
||||||
BoidBrainData bbd;
|
BoidBrainData bbd;
|
||||||
PARTICLE_P;
|
PARTICLE_P;
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
|
|||||||
|
|
||||||
/* determine rotation from velocity */
|
/* determine rotation from velocity */
|
||||||
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
|
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
|
||||||
vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot);
|
vectoquat(pa->state.vel, OB_NEGX, OB_POSZ, pa->state.rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
|
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
|
||||||
@@ -292,6 +292,23 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
|
|||||||
else
|
else
|
||||||
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
|
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
|
||||||
|
|
||||||
|
/* determine velocity from previous location */
|
||||||
|
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
|
||||||
|
if(keys[1].time > keys[2].time) {
|
||||||
|
VecSubf(keys[2].vel, keys[1].co, keys[2].co);
|
||||||
|
VecMulf(keys[2].vel, (keys[1].time - keys[2].time) / frs_sec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VecSubf(keys[2].vel, keys[2].co, keys[1].co);
|
||||||
|
VecMulf(keys[2].vel, (keys[2].time - keys[1].time) / frs_sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine rotation from velocity */
|
||||||
|
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
|
||||||
|
vectoquat(keys[2].vel, OB_NEGX, OB_POSZ, keys[2].rot);
|
||||||
|
}
|
||||||
|
|
||||||
if(cfra > pa->time)
|
if(cfra > pa->time)
|
||||||
cfra1 = MAX2(cfra1, pa->time);
|
cfra1 = MAX2(cfra1, pa->time);
|
||||||
|
|
||||||
@@ -301,7 +318,7 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
|
|||||||
VecMulf(keys[2].vel, dfra / frs_sec);
|
VecMulf(keys[2].vel, dfra / frs_sec);
|
||||||
|
|
||||||
psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
|
psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
|
||||||
QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra);
|
QuatInterpol(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
|
||||||
|
|
||||||
VecMulf(pa->state.vel, frs_sec / dfra);
|
VecMulf(pa->state.vel, frs_sec / dfra);
|
||||||
|
|
||||||
@@ -594,7 +611,8 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
|
|||||||
if(psys->part->phystype == PART_PHYS_BOIDS)
|
if(psys->part->phystype == PART_PHYS_BOIDS)
|
||||||
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
|
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
|
||||||
|
|
||||||
if(psys->part->rotmode || psys->part->avemode)
|
if(psys->part->rotmode!=PART_ROT_VEL
|
||||||
|
|| psys->part->avemode!=PART_AVE_SPIN || psys->part->avefac!=0.0f)
|
||||||
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION);
|
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION);
|
||||||
|
|
||||||
if(psys->part->flag & PART_ROT_DYN)
|
if(psys->part->flag & PART_ROT_DYN)
|
||||||
|
|||||||
@@ -3033,6 +3033,7 @@ static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointC
|
|||||||
static void lib_link_particlesettings(FileData *fd, Main *main)
|
static void lib_link_particlesettings(FileData *fd, Main *main)
|
||||||
{
|
{
|
||||||
ParticleSettings *part;
|
ParticleSettings *part;
|
||||||
|
ParticleDupliWeight *dw;
|
||||||
|
|
||||||
part= main->particle.first;
|
part= main->particle.first;
|
||||||
while(part) {
|
while(part) {
|
||||||
@@ -3048,6 +3049,10 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
|
|||||||
if(part->effector_weights)
|
if(part->effector_weights)
|
||||||
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
|
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
|
||||||
|
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
for(; dw; dw=dw->next)
|
||||||
|
dw->ob = newlibadr(fd, part->id.lib, dw->ob);
|
||||||
|
|
||||||
if(part->boids) {
|
if(part->boids) {
|
||||||
BoidState *state = part->boids->states.first;
|
BoidState *state = part->boids->states.first;
|
||||||
BoidRule *rule;
|
BoidRule *rule;
|
||||||
@@ -3088,6 +3093,8 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
|
|||||||
else
|
else
|
||||||
part->effector_weights = BKE_add_effector_weights(part->eff_group);
|
part->effector_weights = BKE_add_effector_weights(part->eff_group);
|
||||||
|
|
||||||
|
link_list(fd, &part->dupliweights);
|
||||||
|
|
||||||
part->boids= newdataadr(fd, part->boids);
|
part->boids= newdataadr(fd, part->boids);
|
||||||
|
|
||||||
if(part->boids) {
|
if(part->boids) {
|
||||||
|
|||||||
@@ -610,6 +610,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
|
|||||||
static void write_particlesettings(WriteData *wd, ListBase *idbase)
|
static void write_particlesettings(WriteData *wd, ListBase *idbase)
|
||||||
{
|
{
|
||||||
ParticleSettings *part;
|
ParticleSettings *part;
|
||||||
|
ParticleDupliWeight *dw;
|
||||||
|
|
||||||
part= idbase->first;
|
part= idbase->first;
|
||||||
while(part) {
|
while(part) {
|
||||||
@@ -622,6 +623,10 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
|
|||||||
writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
|
writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
|
||||||
writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
|
writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
|
||||||
|
|
||||||
|
dw = part->dupliweights.first;
|
||||||
|
for(; dw; dw=dw->next)
|
||||||
|
writestruct(wd, DATA, "ParticleDupliWeight", 1, dw);
|
||||||
|
|
||||||
if(part->boids && part->phystype == PART_PHYS_BOIDS) {
|
if(part->boids && part->phystype == PART_PHYS_BOIDS) {
|
||||||
BoidState *state = part->boids->states.first;
|
BoidState *state = part->boids->states.first;
|
||||||
|
|
||||||
|
|||||||
@@ -348,6 +348,82 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot)
|
|||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************ move up particle dupliweight operator *********************/
|
||||||
|
|
||||||
|
static int dupliob_move_up_exec(bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
|
||||||
|
ParticleSystem *psys= ptr.data;
|
||||||
|
ParticleSettings *part;
|
||||||
|
ParticleDupliWeight *dw;
|
||||||
|
|
||||||
|
if(!psys)
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
|
part = psys->part;
|
||||||
|
for(dw=part->dupliweights.first; dw; dw=dw->next) {
|
||||||
|
if(dw->flag & PART_DUPLIW_CURRENT && dw->prev) {
|
||||||
|
BLI_remlink(&part->dupliweights, dw);
|
||||||
|
BLI_insertlink(&part->dupliweights, dw->prev->prev, dw);
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
ot->name= "Move Up Dupli Object";
|
||||||
|
ot->idname= "PARTICLE_OT_dupliob_move_up";
|
||||||
|
ot->description= "Move dupli object up in the list.";
|
||||||
|
|
||||||
|
ot->exec= dupliob_move_up_exec;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ move down particle dupliweight operator *********************/
|
||||||
|
|
||||||
|
static int dupliob_move_down_exec(bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
|
||||||
|
ParticleSystem *psys= ptr.data;
|
||||||
|
ParticleSettings *part;
|
||||||
|
ParticleDupliWeight *dw;
|
||||||
|
|
||||||
|
if(!psys)
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
|
part = psys->part;
|
||||||
|
for(dw=part->dupliweights.first; dw; dw=dw->next) {
|
||||||
|
if(dw->flag & PART_DUPLIW_CURRENT && dw->next) {
|
||||||
|
BLI_remlink(&part->dupliweights, dw);
|
||||||
|
BLI_insertlink(&part->dupliweights, dw->next, dw);
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
ot->name= "Move Down Dupli Object";
|
||||||
|
ot->idname= "PARTICLE_OT_dupliob_move_down";
|
||||||
|
ot->description= "Move dupli object down in the list.";
|
||||||
|
|
||||||
|
ot->exec= dupliob_move_down_exec;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
}
|
||||||
|
|
||||||
/************************ connect/disconnect hair operators *********************/
|
/************************ connect/disconnect hair operators *********************/
|
||||||
|
|
||||||
static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
|
static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ void PARTICLE_OT_target_move_down(struct wmOperatorType *ot);
|
|||||||
void PARTICLE_OT_connect_hair(struct wmOperatorType *ot);
|
void PARTICLE_OT_connect_hair(struct wmOperatorType *ot);
|
||||||
void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot);
|
void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot);
|
||||||
|
|
||||||
|
void PARTICLE_OT_dupliob_move_up(struct wmOperatorType *ot);
|
||||||
|
void PARTICLE_OT_dupliob_move_down(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* particle_boids.c */
|
/* particle_boids.c */
|
||||||
void BOID_OT_rule_add(struct wmOperatorType *ot);
|
void BOID_OT_rule_add(struct wmOperatorType *ot);
|
||||||
void BOID_OT_rule_del(struct wmOperatorType *ot);
|
void BOID_OT_rule_del(struct wmOperatorType *ot);
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ static void operatortypes_particle(void)
|
|||||||
WM_operatortype_append(PARTICLE_OT_target_move_down);
|
WM_operatortype_append(PARTICLE_OT_target_move_down);
|
||||||
WM_operatortype_append(PARTICLE_OT_connect_hair);
|
WM_operatortype_append(PARTICLE_OT_connect_hair);
|
||||||
WM_operatortype_append(PARTICLE_OT_disconnect_hair);
|
WM_operatortype_append(PARTICLE_OT_disconnect_hair);
|
||||||
|
|
||||||
|
WM_operatortype_append(PARTICLE_OT_dupliob_move_up);
|
||||||
|
WM_operatortype_append(PARTICLE_OT_dupliob_move_down);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keymap_particle(wmWindowManager *wm)
|
static void keymap_particle(wmWindowManager *wm)
|
||||||
|
|||||||
@@ -3358,7 +3358,30 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* *********** drawing for particles ************* */
|
/* *********** drawing for particles ************* */
|
||||||
|
static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
|
||||||
|
{
|
||||||
|
/* draw created data arrays */
|
||||||
|
switch(draw_as){
|
||||||
|
case PART_DRAW_AXIS:
|
||||||
|
case PART_DRAW_CROSS:
|
||||||
|
glDrawArrays(GL_LINES, 0, 6*totpoint);
|
||||||
|
break;
|
||||||
|
case PART_DRAW_LINE:
|
||||||
|
glDrawArrays(GL_LINES, 0, 2*totpoint);
|
||||||
|
break;
|
||||||
|
case PART_DRAW_BB:
|
||||||
|
if(ob_dt<=OB_WIRE || select)
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||||
|
else
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
|
glDrawArrays(GL_QUADS, 0, 4*totpoint);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
glDrawArrays(GL_POINTS, 0, totpoint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
|
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
|
||||||
{
|
{
|
||||||
float vec[3], vec2[3];
|
float vec[3], vec2[3];
|
||||||
@@ -3401,7 +3424,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
|
|||||||
cd[7]=cd[10]=1.0;
|
cd[7]=cd[10]=1.0;
|
||||||
cd[13]=cd[12]=cd[15]=cd[16]=0.0;
|
cd[13]=cd[12]=cd[15]=cd[16]=0.0;
|
||||||
cd[14]=cd[17]=1.0;
|
cd[14]=cd[17]=1.0;
|
||||||
cd+=18;
|
pdd->cd+=18;
|
||||||
|
|
||||||
VECCOPY(vec2,state->co);
|
VECCOPY(vec2,state->co);
|
||||||
}
|
}
|
||||||
@@ -3552,7 +3575,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0)
|
if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(part->draw_as==PART_DRAW_NOT) return;
|
if(part->draw_as == PART_DRAW_REND)
|
||||||
|
draw_as = part->ren_as;
|
||||||
|
else
|
||||||
|
draw_as = part->draw_as;
|
||||||
|
|
||||||
|
if(draw_as == PART_DRAW_NOT)
|
||||||
|
return;
|
||||||
|
|
||||||
/* 2. */
|
/* 2. */
|
||||||
sim.psmd = psmd = psys_get_modifier(ob,psys);
|
sim.psmd = psmd = psys_get_modifier(ob,psys);
|
||||||
@@ -3582,26 +3611,22 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
|
|
||||||
if(v3d->zbuf) glDepthMask(1);
|
if(v3d->zbuf) glDepthMask(1);
|
||||||
|
|
||||||
if(select)
|
if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
|
||||||
cpack(0xFFFFFF);
|
|
||||||
else if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
|
|
||||||
glColor3f(ma->r,ma->g,ma->b);
|
glColor3f(ma->r,ma->g,ma->b);
|
||||||
|
|
||||||
ma_r = ma->r;
|
ma_r = ma->r;
|
||||||
ma_g = ma->g;
|
ma_g = ma->g;
|
||||||
ma_b = ma->b;
|
ma_b = ma->b;
|
||||||
|
|
||||||
if(pdd) {
|
|
||||||
pdd->ma_r = &ma_r;
|
|
||||||
pdd->ma_g = &ma_g;
|
|
||||||
pdd->ma_b = &ma_b;
|
|
||||||
}
|
|
||||||
|
|
||||||
create_cdata = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cpack(0);
|
cpack(0);
|
||||||
|
|
||||||
|
if(pdd) {
|
||||||
|
pdd->ma_r = &ma_r;
|
||||||
|
pdd->ma_g = &ma_g;
|
||||||
|
pdd->ma_b = &ma_b;
|
||||||
|
}
|
||||||
|
|
||||||
timestep= psys_get_timestep(&sim);
|
timestep= psys_get_timestep(&sim);
|
||||||
|
|
||||||
if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
|
if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
|
||||||
@@ -3612,11 +3637,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
|
|
||||||
totpart=psys->totpart;
|
totpart=psys->totpart;
|
||||||
|
|
||||||
if(part->draw_as==PART_DRAW_REND)
|
|
||||||
draw_as = part->ren_as;
|
|
||||||
else
|
|
||||||
draw_as = part->draw_as;
|
|
||||||
|
|
||||||
//if(part->flag&PART_GLOB_TIME)
|
//if(part->flag&PART_GLOB_TIME)
|
||||||
cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
|
cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
|
||||||
|
|
||||||
@@ -3646,6 +3666,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
pixsize*=2.0;
|
pixsize*=2.0;
|
||||||
else
|
else
|
||||||
pixsize*=part->draw_size;
|
pixsize*=part->draw_size;
|
||||||
|
|
||||||
|
if(draw_as==PART_DRAW_AXIS)
|
||||||
|
create_cdata = 1;
|
||||||
break;
|
break;
|
||||||
case PART_DRAW_OB:
|
case PART_DRAW_OB:
|
||||||
if(part->dup_ob==0)
|
if(part->dup_ob==0)
|
||||||
@@ -3693,9 +3716,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
Normalize(imat[1]);
|
Normalize(imat[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!create_cdata && pdd && pdd->cdata) {
|
||||||
|
MEM_freeN(pdd->cdata);
|
||||||
|
pdd->cdata = pdd->cd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* 4. */
|
/* 4. */
|
||||||
if(draw_as && draw_as!=PART_DRAW_PATH) {
|
if(draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC)==0) {
|
||||||
int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
|
int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
|
||||||
|
int create_ndata = 0;
|
||||||
|
|
||||||
if(!pdd)
|
if(!pdd)
|
||||||
pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
|
pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
|
||||||
@@ -3705,37 +3734,36 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
psys_make_temp_pointcache(ob, psys);
|
psys_make_temp_pointcache(ob, psys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(draw_as) {
|
||||||
|
case PART_DRAW_AXIS:
|
||||||
|
case PART_DRAW_CROSS:
|
||||||
|
tot_vec_size *= 6;
|
||||||
|
if(draw_as != PART_DRAW_CROSS)
|
||||||
|
create_cdata = 1;
|
||||||
|
break;
|
||||||
|
case PART_DRAW_LINE:
|
||||||
|
tot_vec_size *= 2;
|
||||||
|
break;
|
||||||
|
case PART_DRAW_BB:
|
||||||
|
tot_vec_size *= 4;
|
||||||
|
create_ndata = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(pdd->tot_vec_size != tot_vec_size)
|
if(pdd->tot_vec_size != tot_vec_size)
|
||||||
psys_free_pdd(psys);
|
psys_free_pdd(psys);
|
||||||
|
|
||||||
if(draw_as!=PART_DRAW_CIRC) {
|
if(!pdd->vdata)
|
||||||
switch(draw_as) {
|
pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata");
|
||||||
case PART_DRAW_AXIS:
|
if(create_cdata && !pdd->cdata)
|
||||||
case PART_DRAW_CROSS:
|
pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata");
|
||||||
if(draw_as != PART_DRAW_CROSS || create_cdata)
|
if(create_ndata && !pdd->ndata)
|
||||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
|
pdd->ndata = MEM_callocN(tot_vec_size, "particle_vdata");
|
||||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
|
|
||||||
break;
|
|
||||||
case PART_DRAW_LINE:
|
|
||||||
if(create_cdata)
|
|
||||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
|
|
||||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
|
|
||||||
break;
|
|
||||||
case PART_DRAW_BB:
|
|
||||||
if(create_cdata)
|
|
||||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
|
|
||||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
|
||||||
if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(create_cdata)
|
|
||||||
if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata");
|
|
||||||
if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
|
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
|
||||||
if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
|
if(!pdd->vedata)
|
||||||
|
pdd->vedata = MEM_callocN(2 * (totpart + totchild) * 3 * sizeof(float), "particle_vedata");
|
||||||
|
|
||||||
need_v = 1;
|
need_v = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3744,11 +3772,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
pdd->cd= pdd->cdata;
|
pdd->cd= pdd->cdata;
|
||||||
pdd->nd= pdd->ndata;
|
pdd->nd= pdd->ndata;
|
||||||
pdd->tot_vec_size= tot_vec_size;
|
pdd->tot_vec_size= tot_vec_size;
|
||||||
|
|
||||||
psys->lattice= psys_get_lattice(&sim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(draw_as){
|
psys->lattice= psys_get_lattice(&sim);
|
||||||
|
|
||||||
|
if(draw_as!=PART_DRAW_PATH){
|
||||||
/* 5. */
|
/* 5. */
|
||||||
if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED)
|
if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED)
|
||||||
&& (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) {
|
&& (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) {
|
||||||
@@ -3836,156 +3864,139 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
r_length = PSYS_FRAND(a + 22);
|
r_length = PSYS_FRAND(a + 22);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(draw_as!=PART_DRAW_PATH){
|
drawn = 0;
|
||||||
drawn = 0;
|
if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
|
||||||
if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
|
float length = part->path_end * (1.0 - part->randlength * r_length);
|
||||||
float length = part->path_end * (1.0 - part->randlength * r_length);
|
int trail_count = part->trail_count * (1.0 - part->randlength * r_length);
|
||||||
int trail_count = part->trail_count * (1.0 - part->randlength * r_length);
|
float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
|
||||||
float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
|
float dt = length / (trail_count ? (float)trail_count : 1.0f);
|
||||||
float dt = length / (trail_count ? (float)trail_count : 1.0f);
|
int i=0;
|
||||||
int i=0;
|
|
||||||
|
|
||||||
ct+=dt;
|
ct+=dt;
|
||||||
for(i=0; i < trail_count; i++, ct += dt) {
|
for(i=0; i < trail_count; i++, ct += dt) {
|
||||||
if(part->draw & PART_ABS_PATH_TIME) {
|
if(part->draw & PART_ABS_PATH_TIME) {
|
||||||
if(ct < pa_birthtime || ct > pa_dietime)
|
if(ct < pa_birthtime || ct > pa_dietime)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(ct < 0.0f || ct > 1.0f)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
|
|
||||||
psys_get_particle_on_path(&sim,a,&state,need_v);
|
|
||||||
|
|
||||||
if(psys->parent)
|
|
||||||
Mat4MulVecfl(psys->parent->obmat, state.co);
|
|
||||||
|
|
||||||
/* create actiual particle data */
|
|
||||||
if(draw_as == PART_DRAW_BB) {
|
|
||||||
bb.size = pa_size;
|
|
||||||
bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
|
|
||||||
bb.time = ct;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
|
|
||||||
|
|
||||||
totpoint++;
|
|
||||||
drawn = 1;
|
|
||||||
}
|
}
|
||||||
|
else if(ct < 0.0f || ct > 1.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
|
||||||
|
psys_get_particle_on_path(&sim,a,&state,need_v);
|
||||||
|
|
||||||
|
if(psys->parent)
|
||||||
|
Mat4MulVecfl(psys->parent->obmat, state.co);
|
||||||
|
|
||||||
|
/* create actiual particle data */
|
||||||
|
if(draw_as == PART_DRAW_BB) {
|
||||||
|
bb.size = pa_size;
|
||||||
|
bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
|
||||||
|
bb.time = ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
|
||||||
|
|
||||||
|
totpoint++;
|
||||||
|
drawn = 1;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
state.time=cfra;
|
{
|
||||||
if(psys_get_particle_state(&sim,a,&state,0)){
|
state.time=cfra;
|
||||||
if(psys->parent)
|
if(psys_get_particle_state(&sim,a,&state,0)){
|
||||||
Mat4MulVecfl(psys->parent->obmat, state.co);
|
if(psys->parent)
|
||||||
|
Mat4MulVecfl(psys->parent->obmat, state.co);
|
||||||
|
|
||||||
/* create actiual particle data */
|
/* create actiual particle data */
|
||||||
if(draw_as == PART_DRAW_BB) {
|
if(draw_as == PART_DRAW_BB) {
|
||||||
bb.size = pa_size;
|
bb.size = pa_size;
|
||||||
bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
|
bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
|
||||||
bb.time = pa_time;
|
bb.time = pa_time;
|
||||||
}
|
|
||||||
|
|
||||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
|
|
||||||
|
|
||||||
totpoint++;
|
|
||||||
drawn = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
|
||||||
|
|
||||||
|
totpoint++;
|
||||||
|
drawn = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawn) {
|
||||||
|
/* additional things to draw for each particle */
|
||||||
|
/* (velocity, size and number) */
|
||||||
|
if(pdd->vedata){
|
||||||
|
VECCOPY(pdd->ved,state.co);
|
||||||
|
pdd->ved+=3;
|
||||||
|
VECCOPY(vel,state.vel);
|
||||||
|
VecMulf(vel,timestep);
|
||||||
|
VECADD(pdd->ved,state.co,vel);
|
||||||
|
pdd->ved+=3;
|
||||||
|
|
||||||
|
totve++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(drawn) {
|
if(part->draw & PART_DRAW_SIZE){
|
||||||
/* additional things to draw for each particle */
|
setlinestyle(3);
|
||||||
/* (velocity, size and number) */
|
drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
|
||||||
if(pdd->vedata){
|
setlinestyle(0);
|
||||||
VECCOPY(pdd->ved,state.co);
|
}
|
||||||
pdd->ved+=3;
|
|
||||||
VECCOPY(vel,state.vel);
|
|
||||||
VecMulf(vel,timestep);
|
|
||||||
VECADD(pdd->ved,state.co,vel);
|
|
||||||
pdd->ved+=3;
|
|
||||||
|
|
||||||
totve++;
|
if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){
|
||||||
}
|
val[0]= '\0';
|
||||||
|
|
||||||
|
if(part->draw&PART_DRAW_NUM)
|
||||||
|
sprintf(val, " %i", a);
|
||||||
|
|
||||||
if(part->draw & PART_DRAW_SIZE){
|
if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH)
|
||||||
setlinestyle(3);
|
sprintf(val, "%s:", val);
|
||||||
drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
|
|
||||||
setlinestyle(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){
|
if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS)
|
||||||
val[0]= '\0';
|
sprintf(val, "%s %.2f", val, pa_health);
|
||||||
|
|
||||||
if(part->draw&PART_DRAW_NUM)
|
|
||||||
sprintf(val, " %i", a);
|
|
||||||
|
|
||||||
if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH)
|
/* in path drawing state.co is the end point */
|
||||||
sprintf(val, "%s:", val);
|
view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
|
||||||
|
|
||||||
if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS)
|
|
||||||
sprintf(val, "%s %.2f", val, pa_health);
|
|
||||||
|
|
||||||
/* in path drawing state.co is the end point */
|
|
||||||
view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* 6. */
|
/* 6. */
|
||||||
|
|
||||||
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
|
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
if(draw_as==PART_DRAW_PATH){
|
if(draw_as==PART_DRAW_PATH){
|
||||||
ParticleCacheKey **cache, *path;
|
ParticleCacheKey **cache, *path;
|
||||||
float *cd2=0,*cdata2=0;
|
float *cd2=0,*cdata2=0;
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
/* setup gl flags */
|
/* setup gl flags */
|
||||||
if(ob_dt > OB_WIRE) {
|
if(ob_dt > OB_WIRE) {
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
if(part->draw&PART_DRAW_MAT_COL)
|
if(part->draw&PART_DRAW_MAT_COL)
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
UI_ThemeColor(TH_WIRE);
|
UI_ThemeColor(TH_WIRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(totchild && (part->draw&PART_DRAW_PARENT)==0)
|
if(totchild && (part->draw&PART_DRAW_PARENT)==0)
|
||||||
totpart=0;
|
totpart=0;
|
||||||
|
|
||||||
/* draw actual/parent particles */
|
/* draw actual/parent particles */
|
||||||
cache=psys->pathcache;
|
cache=psys->pathcache;
|
||||||
for(a=0, pa=psys->particles; a<totpart; a++, pa++){
|
for(a=0, pa=psys->particles; a<totpart; a++, pa++){
|
||||||
path=cache[a];
|
path=cache[a];
|
||||||
if(path->steps > 0) {
|
if(path->steps > 0) {
|
||||||
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
|
|
||||||
|
|
||||||
if(ob_dt > OB_WIRE) {
|
|
||||||
glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
|
|
||||||
if(part->draw&PART_DRAW_MAT_COL)
|
|
||||||
glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw child particles */
|
|
||||||
cache=psys->childcache;
|
|
||||||
for(a=0; a<totchild; a++){
|
|
||||||
path=cache[a];
|
|
||||||
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
|
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
|
||||||
|
|
||||||
if(ob_dt > OB_WIRE) {
|
if(ob_dt > OB_WIRE) {
|
||||||
@@ -3996,85 +4007,103 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
|
|
||||||
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
|
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw child particles */
|
||||||
|
cache=psys->childcache;
|
||||||
|
for(a=0; a<totchild; a++){
|
||||||
|
path=cache[a];
|
||||||
|
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
|
||||||
|
|
||||||
|
|
||||||
/* restore & clean up */
|
|
||||||
if(ob_dt > OB_WIRE) {
|
if(ob_dt > OB_WIRE) {
|
||||||
|
glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
|
||||||
if(part->draw&PART_DRAW_MAT_COL)
|
if(part->draw&PART_DRAW_MAT_COL)
|
||||||
glDisable(GL_COLOR_ARRAY);
|
glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cdata2)
|
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
|
||||||
MEM_freeN(cdata2);
|
|
||||||
cd2=cdata2=0;
|
|
||||||
|
|
||||||
glLineWidth(1.0f);
|
|
||||||
}
|
|
||||||
else if(draw_as!=PART_DRAW_CIRC){
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
|
|
||||||
/* setup created data arrays */
|
|
||||||
if(pdd->vdata){
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
|
|
||||||
/* billboards are drawn this way */
|
|
||||||
if(pdd->ndata && ob_dt>OB_WIRE){
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glNormalPointer(GL_FLOAT, 0, pdd->ndata);
|
|
||||||
glEnable(GL_LIGHTING);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pdd->cdata){
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw created data arrays */
|
|
||||||
switch(draw_as){
|
|
||||||
case PART_DRAW_AXIS:
|
|
||||||
case PART_DRAW_CROSS:
|
|
||||||
glDrawArrays(GL_LINES, 0, 6*totpoint);
|
|
||||||
break;
|
|
||||||
case PART_DRAW_LINE:
|
|
||||||
glDrawArrays(GL_LINES, 0, 2*totpoint);
|
|
||||||
break;
|
|
||||||
case PART_DRAW_BB:
|
|
||||||
if(ob_dt<=OB_WIRE)
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
|
||||||
|
|
||||||
glDrawArrays(GL_QUADS, 0, 4*totpoint);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
glDrawArrays(GL_POINTS, 0, totpoint);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
|
|
||||||
pdd->totpoint = totpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pdd->vedata){
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
/* restore & clean up */
|
||||||
cpack(0xC0C0C0);
|
if(ob_dt > OB_WIRE) {
|
||||||
|
if(part->draw&PART_DRAW_MAT_COL)
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glDisable(GL_COLOR_ARRAY);
|
||||||
glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
|
|
||||||
glDrawArrays(GL_LINES, 0, 2*totve);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT, polygonmode[0]);
|
if(cdata2)
|
||||||
glPolygonMode(GL_BACK, polygonmode[1]);
|
MEM_freeN(cdata2);
|
||||||
|
cd2=cdata2=0;
|
||||||
|
|
||||||
|
glLineWidth(1.0f);
|
||||||
}
|
}
|
||||||
|
else if(ELEM(draw_as, 0, PART_DRAW_CIRC)==0){
|
||||||
|
int point_size = 1;
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
/* enable point data array */
|
||||||
|
if(pdd->vdata){
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
|
if(select) {
|
||||||
|
UI_ThemeColor(TH_ACTIVE);
|
||||||
|
|
||||||
|
if(part->draw_size)
|
||||||
|
glPointSize(part->draw_size + 2);
|
||||||
|
else
|
||||||
|
glPointSize(4.0);
|
||||||
|
|
||||||
|
glLineWidth(3.0);
|
||||||
|
|
||||||
|
draw_particle_arrays(draw_as, totpoint, ob_dt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore from select */
|
||||||
|
glColor3f(ma_r,ma_g,ma_b);
|
||||||
|
glPointSize(part->draw_size ? part->draw_size : 2.0);
|
||||||
|
glLineWidth(1.0);
|
||||||
|
|
||||||
|
/* enable other data arrays */
|
||||||
|
|
||||||
|
/* billboards are drawn this way */
|
||||||
|
if(pdd->ndata && ob_dt>OB_WIRE){
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glNormalPointer(GL_FLOAT, 0, pdd->ndata);
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pdd->cdata){
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_particle_arrays(draw_as, totpoint, ob_dt, 0);
|
||||||
|
|
||||||
|
pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
|
||||||
|
pdd->totpoint = totpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pdd && pdd->vedata){
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
cpack(0xC0C0C0);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
|
||||||
|
|
||||||
|
glDrawArrays(GL_LINES, 0, 2*totve);
|
||||||
|
}
|
||||||
|
|
||||||
|
glPolygonMode(GL_FRONT, polygonmode[0]);
|
||||||
|
glPolygonMode(GL_BACK, polygonmode[1]);
|
||||||
|
|
||||||
/* 7. */
|
/* 7. */
|
||||||
|
|
||||||
@@ -4087,6 +4116,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||||||
|
|
||||||
psys->flag &= ~PSYS_DRAWING;
|
psys->flag &= ~PSYS_DRAWING;
|
||||||
|
|
||||||
|
/* draw data can't be saved for billboards as they must update to target changes */
|
||||||
|
if(draw_as == PART_DRAW_BB) {
|
||||||
|
psys_free_pdd(psys);
|
||||||
|
pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
|
||||||
|
}
|
||||||
|
|
||||||
if(psys->lattice){
|
if(psys->lattice){
|
||||||
end_latt_deform(psys->lattice);
|
end_latt_deform(psys->lattice);
|
||||||
psys->lattice= NULL;
|
psys->lattice= NULL;
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ typedef enum PFieldType {
|
|||||||
} PFieldType;
|
} PFieldType;
|
||||||
|
|
||||||
typedef struct PartDeflect {
|
typedef struct PartDeflect {
|
||||||
|
int flag; /* general settings flag */
|
||||||
short deflect; /* Deflection flag - does mesh deflect particles */
|
short deflect; /* Deflection flag - does mesh deflect particles */
|
||||||
short forcefield; /* Force field type, do the vertices attract / repel particles? */
|
short forcefield; /* Force field type, do the vertices attract / repel particles? */
|
||||||
short flag; /* general settings flag */
|
|
||||||
short falloff; /* fall-off type */
|
short falloff; /* fall-off type */
|
||||||
short shape; /* point, plane or surface */
|
short shape; /* point, plane or surface */
|
||||||
short tex_mode; /* texture effector */
|
short tex_mode; /* texture effector */
|
||||||
short kink, kink_axis; /* for curve guide */
|
short kink, kink_axis; /* for curve guide */
|
||||||
short zdir, rt;
|
short zdir;
|
||||||
|
|
||||||
/* Main effector values */
|
/* Main effector values */
|
||||||
float f_strength; /* The strength of the force (+ or - ) */
|
float f_strength; /* The strength of the force (+ or - ) */
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ typedef struct ParticleTarget {
|
|||||||
float time, duration;
|
float time, duration;
|
||||||
} ParticleTarget;
|
} ParticleTarget;
|
||||||
|
|
||||||
|
typedef struct ParticleDupliWeight {
|
||||||
|
struct ParticleDupliWeight *next, *prev;
|
||||||
|
struct Object *ob;
|
||||||
|
short count;
|
||||||
|
short flag, rt[2];
|
||||||
|
} ParticleDupliWeight;
|
||||||
|
|
||||||
typedef struct ParticleData {
|
typedef struct ParticleData {
|
||||||
ParticleKey state; /* current global coordinates */
|
ParticleKey state; /* current global coordinates */
|
||||||
|
|
||||||
@@ -148,6 +155,7 @@ typedef struct ParticleSettings {
|
|||||||
|
|
||||||
/* initial velocity factors */
|
/* initial velocity factors */
|
||||||
float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
|
float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
|
||||||
|
float ob_vel[3], rt;
|
||||||
float avefac, phasefac, randrotfac, randphasefac;
|
float avefac, phasefac, randrotfac, randphasefac;
|
||||||
/* physical properties */
|
/* physical properties */
|
||||||
float mass, size, randsize, reactshape;
|
float mass, size, randsize, reactshape;
|
||||||
@@ -179,6 +187,7 @@ typedef struct ParticleSettings {
|
|||||||
int keyed_loops;
|
int keyed_loops;
|
||||||
|
|
||||||
struct Group *dup_group;
|
struct Group *dup_group;
|
||||||
|
struct ListBase dupliweights;
|
||||||
struct Group *eff_group; // deprecated
|
struct Group *eff_group; // deprecated
|
||||||
struct Object *dup_ob;
|
struct Object *dup_ob;
|
||||||
struct Object *bb_ob;
|
struct Object *bb_ob;
|
||||||
@@ -324,12 +333,12 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||||||
|
|
||||||
/* part->draw */
|
/* part->draw */
|
||||||
#define PART_DRAW_VEL 1
|
#define PART_DRAW_VEL 1
|
||||||
//#define PART_DRAW_PATH_LEN 2
|
#define PART_DRAW_GLOBAL_OB 2
|
||||||
#define PART_DRAW_SIZE 4
|
#define PART_DRAW_SIZE 4
|
||||||
#define PART_DRAW_EMITTER 8 /* render emitter also */
|
#define PART_DRAW_EMITTER 8 /* render emitter also */
|
||||||
#define PART_DRAW_HEALTH 16
|
#define PART_DRAW_HEALTH 16
|
||||||
#define PART_ABS_PATH_TIME 32
|
#define PART_ABS_PATH_TIME 32
|
||||||
//#define PART_DRAW_TRAIL 64 /* deprecated */
|
#define PART_DRAW_COUNT_GR 64
|
||||||
#define PART_DRAW_BB_LOCK 128
|
#define PART_DRAW_BB_LOCK 128
|
||||||
#define PART_DRAW_PARENT 256
|
#define PART_DRAW_PARENT 256
|
||||||
#define PART_DRAW_NUM 512
|
#define PART_DRAW_NUM 512
|
||||||
@@ -444,6 +453,9 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||||||
#define PARS_ALIVE 3
|
#define PARS_ALIVE 3
|
||||||
#define PARS_DYING 4
|
#define PARS_DYING 4
|
||||||
|
|
||||||
|
/* ParticleDupliWeight->flag */
|
||||||
|
#define PART_DUPLIW_CURRENT 1
|
||||||
|
|
||||||
/* psys->vg */
|
/* psys->vg */
|
||||||
#define PSYS_TOT_VG 12
|
#define PSYS_TOT_VG 12
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ EnumPropertyItem effector_shape_items[] = {
|
|||||||
{0, NULL, 0, NULL, NULL}
|
{0, NULL, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnumPropertyItem curve_shape_items[] = {
|
||||||
|
{PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""},
|
||||||
|
{PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""},
|
||||||
|
{PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Curve", ""},
|
||||||
|
{0, NULL, 0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
EnumPropertyItem empty_shape_items[] = {
|
EnumPropertyItem empty_shape_items[] = {
|
||||||
{PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""},
|
{PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""},
|
||||||
{PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""},
|
{PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""},
|
||||||
@@ -59,6 +66,13 @@ EnumPropertyItem vortex_shape_items[] = {
|
|||||||
{0, NULL, 0, NULL, NULL}
|
{0, NULL, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnumPropertyItem curve_vortex_shape_items[] = {
|
||||||
|
{PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""},
|
||||||
|
{PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""},
|
||||||
|
{PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Curve (New)", ""},
|
||||||
|
{0, NULL, 0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
EnumPropertyItem empty_vortex_shape_items[] = {
|
EnumPropertyItem empty_vortex_shape_items[] = {
|
||||||
{PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""},
|
{PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""},
|
||||||
{PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""},
|
{PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""},
|
||||||
@@ -538,9 +552,11 @@ static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr,
|
|||||||
|
|
||||||
/* needed for doc generation */
|
/* needed for doc generation */
|
||||||
RNA_enum_items_add(&item, &totitem, effector_shape_items);
|
RNA_enum_items_add(&item, &totitem, effector_shape_items);
|
||||||
|
RNA_enum_items_add(&item, &totitem, curve_shape_items);
|
||||||
RNA_enum_items_add(&item, &totitem, empty_shape_items);
|
RNA_enum_items_add(&item, &totitem, empty_shape_items);
|
||||||
RNA_enum_items_add(&item, &totitem, vortex_shape_items);
|
RNA_enum_items_add(&item, &totitem, vortex_shape_items);
|
||||||
RNA_enum_items_add(&item, &totitem, empty_shape_items);
|
RNA_enum_items_add(&item, &totitem, curve_vortex_shape_items);
|
||||||
|
RNA_enum_items_add(&item, &totitem, empty_vortex_shape_items);
|
||||||
RNA_enum_item_end(&item, &totitem);
|
RNA_enum_item_end(&item, &totitem);
|
||||||
|
|
||||||
*free= 1;
|
*free= 1;
|
||||||
@@ -553,7 +569,13 @@ static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr,
|
|||||||
|
|
||||||
ob= (Object*)ptr->id.data;
|
ob= (Object*)ptr->id.data;
|
||||||
|
|
||||||
if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
|
if(ob->type == OB_CURVE) {
|
||||||
|
if(ob->pd->forcefield == PFIELD_VORTEX)
|
||||||
|
return curve_vortex_shape_items;
|
||||||
|
|
||||||
|
return curve_shape_items;
|
||||||
|
}
|
||||||
|
else if(ELEM3(ob->type, OB_MESH, OB_SURF, OB_FONT)) {
|
||||||
if(ob->pd->forcefield == PFIELD_VORTEX)
|
if(ob->pd->forcefield == PFIELD_VORTEX)
|
||||||
return vortex_shape_items;
|
return vortex_shape_items;
|
||||||
|
|
||||||
@@ -783,11 +805,11 @@ static void rna_def_effector_weight(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "All", "All effector's weight.");
|
RNA_def_property_ui_text(prop, "All", "All effector's weight.");
|
||||||
RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
|
RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "spherical", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "force", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_float_sdna(prop, NULL, "weight[1]");
|
RNA_def_property_float_sdna(prop, NULL, "weight[1]");
|
||||||
RNA_def_property_range(prop, -200.0f, 200.0f);
|
RNA_def_property_range(prop, -200.0f, 200.0f);
|
||||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
|
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
|
||||||
RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight.");
|
RNA_def_property_ui_text(prop, "Force", "Force effector weight.");
|
||||||
RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
|
RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "vortex", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "vortex", PROP_FLOAT, PROP_NONE);
|
||||||
@@ -1113,6 +1135,11 @@ static void rna_def_field(BlenderRNA *brna)
|
|||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_ROTATION);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_ROTATION);
|
||||||
RNA_def_property_ui_text(prop, "Rotation", "Effect particles' dynamic rotation");
|
RNA_def_property_ui_text(prop, "Rotation", "Effect particles' dynamic rotation");
|
||||||
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
|
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "do_absorption", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_VISIBILITY);
|
||||||
|
RNA_def_property_ui_text(prop, "Absorption", "Force gets absorbed by collision objects");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
|
||||||
|
|
||||||
/* Pointer */
|
/* Pointer */
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ EnumPropertyItem part_hair_ren_as_items[] = {
|
|||||||
#include "BKE_pointcache.h"
|
#include "BKE_pointcache.h"
|
||||||
|
|
||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
|
#include "BLI_listbase.h"
|
||||||
|
|
||||||
/* property update functions */
|
/* property update functions */
|
||||||
static void particle_recalc(bContext *C, PointerRNA *ptr, short flag)
|
static void particle_recalc(bContext *C, PointerRNA *ptr, short flag)
|
||||||
@@ -433,6 +434,71 @@ static int rna_ParticleSystem_edited_get(PointerRNA *ptr)
|
|||||||
else
|
else
|
||||||
return (psys->pointcache->edit && psys->pointcache->edit->edited);
|
return (psys->pointcache->edit && psys->pointcache->edit->edited);
|
||||||
}
|
}
|
||||||
|
static PointerRNA rna_ParticleDupliWeight_active_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
ParticleSettings *part= (ParticleSettings*)ptr->id.data;
|
||||||
|
ParticleDupliWeight *dw = part->dupliweights.first;
|
||||||
|
|
||||||
|
for(; dw; dw=dw->next) {
|
||||||
|
if(dw->flag & PART_DUPLIW_CURRENT)
|
||||||
|
return rna_pointer_inherit_refine(ptr, &RNA_ParticleDupliWeight, dw);
|
||||||
|
}
|
||||||
|
return rna_pointer_inherit_refine(ptr, &RNA_ParticleTarget, NULL);
|
||||||
|
}
|
||||||
|
static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min, int *max)
|
||||||
|
{
|
||||||
|
ParticleSettings *part= (ParticleSettings*)ptr->id.data;
|
||||||
|
*min= 0;
|
||||||
|
*max= BLI_countlist(&part->dupliweights)-1;
|
||||||
|
*max= MAX2(0, *max);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_ParticleDupliWeight_active_index_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
ParticleSettings *part= (ParticleSettings*)ptr->id.data;
|
||||||
|
ParticleDupliWeight *dw = part->dupliweights.first;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
for(; dw; dw=dw->next, i++)
|
||||||
|
if(dw->flag & PART_DUPLIW_CURRENT)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int value)
|
||||||
|
{
|
||||||
|
ParticleSettings *part= (ParticleSettings*)ptr->id.data;
|
||||||
|
ParticleDupliWeight *dw = part->dupliweights.first;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
for(; dw; dw=dw->next, i++) {
|
||||||
|
if(i==value)
|
||||||
|
dw->flag |= PART_DUPLIW_CURRENT;
|
||||||
|
else
|
||||||
|
dw->flag &= ~PART_DUPLIW_CURRENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_ParticleDupliWeight_name_length(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
ParticleDupliWeight *dw= ptr->data;
|
||||||
|
|
||||||
|
if(dw->ob)
|
||||||
|
return strlen(dw->ob->id.name+2) + 7;
|
||||||
|
else
|
||||||
|
return 9 + 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str)
|
||||||
|
{
|
||||||
|
ParticleDupliWeight *dw= ptr->data;
|
||||||
|
|
||||||
|
if(dw->ob)
|
||||||
|
sprintf(str, "%s: %i", dw->ob->id.name+2, dw->count);
|
||||||
|
else
|
||||||
|
strcpy(str, "No object");
|
||||||
|
}
|
||||||
EnumPropertyItem from_items[] = {
|
EnumPropertyItem from_items[] = {
|
||||||
{PART_FROM_VERT, "VERT", 0, "Vertexes", ""},
|
{PART_FROM_VERT, "VERT", 0, "Vertexes", ""},
|
||||||
{PART_FROM_FACE, "FACE", 0, "Faces", ""},
|
{PART_FROM_FACE, "FACE", 0, "Faces", ""},
|
||||||
@@ -726,6 +792,27 @@ static void rna_def_particle(BlenderRNA *brna)
|
|||||||
// short rt2;
|
// short rt2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_particle_dupliweight(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "ParticleDupliWeight", NULL);
|
||||||
|
RNA_def_struct_ui_text(srna, "Particle Dupliobject Weight", "Weight of a particle dupliobject in a group.");
|
||||||
|
RNA_def_struct_sdna(srna, "ParticleDupliWeight");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_funcs(prop, "rna_ParticleDupliWeight_name_get", "rna_ParticleDupliWeight_name_length", NULL);
|
||||||
|
RNA_def_property_ui_text(prop, "Name", "Particle dupliobject name.");
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "count", PROP_INT, PROP_UNSIGNED);
|
||||||
|
RNA_def_property_range(prop, 0, INT_MAX);
|
||||||
|
RNA_def_property_ui_text(prop, "Count", "The number of times this object is repeated with respect to other objects.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_def_particle_settings(BlenderRNA *brna)
|
static void rna_def_particle_settings(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
@@ -1069,6 +1156,16 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from group randomly");
|
RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from group randomly");
|
||||||
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "use_group_count", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_COUNT_GR);
|
||||||
|
RNA_def_property_ui_text(prop, "Use Count", "Use object multiple times in the same group");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "use_global_dupli", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_GLOBAL_OB);
|
||||||
|
RNA_def_property_ui_text(prop, "Use Global", "Use object's global coordinates for duplication.");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "render_adaptive", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "render_adaptive", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_ADAPT);
|
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_ADAPT);
|
||||||
RNA_def_property_ui_text(prop, "Adaptive render", "Draw steps of the particle path");
|
RNA_def_property_ui_text(prop, "Adaptive render", "Draw steps of the particle path");
|
||||||
@@ -1374,6 +1471,13 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Reactor", "Let the vector away from the target particles location give the particle a starting speed.");
|
RNA_def_property_ui_text(prop, "Reactor", "Let the vector away from the target particles location give the particle a starting speed.");
|
||||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "object_aligned_factor", PROP_FLOAT, PROP_VELOCITY);
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "ob_vel");
|
||||||
|
RNA_def_property_array(prop, 3);
|
||||||
|
RNA_def_property_range(prop, -200.0f, 200.0f);
|
||||||
|
RNA_def_property_ui_text(prop, "Object Aligned", "Let the emitter object orientation give the particle a starting speed");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "angular_velocity_factor", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "angular_velocity_factor", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_float_sdna(prop, NULL, "avefac");
|
RNA_def_property_float_sdna(prop, NULL, "avefac");
|
||||||
RNA_def_property_range(prop, -200.0f, 200.0f);
|
RNA_def_property_range(prop, -200.0f, 200.0f);
|
||||||
@@ -1426,19 +1530,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||||||
|
|
||||||
|
|
||||||
/* global physical properties */
|
/* global physical properties */
|
||||||
prop= RNA_def_property(srna, "acceleration", PROP_FLOAT, PROP_ACCELERATION);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "acc");
|
|
||||||
RNA_def_property_array(prop, 3);
|
|
||||||
RNA_def_property_range(prop, -200.0f, 200.0f);
|
|
||||||
RNA_def_property_ui_text(prop, "Acceleration", "Constant acceleration");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "acc[2]");
|
|
||||||
RNA_def_property_range(prop, -200.0f, 200.0f);
|
|
||||||
RNA_def_property_ui_text(prop, "Gravity", "Constant acceleration in global Z axis direction");
|
|
||||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_float_sdna(prop, NULL, "dragfac");
|
RNA_def_property_float_sdna(prop, NULL, "dragfac");
|
||||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||||
@@ -1665,6 +1756,19 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Dupli Group", "Show Objects in this Group in place of particles");
|
RNA_def_property_ui_text(prop, "Dupli Group", "Show Objects in this Group in place of particles");
|
||||||
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "dupliweights", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "ParticleDupliWeight");
|
||||||
|
RNA_def_property_ui_text(prop, "Dupli Group Weights", "Weights for all of the objects in the dupli group.");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "active_dupliweight", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "ParticleDupliWeight");
|
||||||
|
RNA_def_property_pointer_funcs(prop, "rna_ParticleDupliWeight_active_get", NULL, NULL);
|
||||||
|
RNA_def_property_ui_text(prop, "Active Dupli Object", "");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "active_dupliweight_index", PROP_INT, PROP_UNSIGNED);
|
||||||
|
RNA_def_property_int_funcs(prop, "rna_ParticleDupliWeight_active_index_get", "rna_ParticleDupliWeight_active_index_set", "rna_ParticleDupliWeight_active_index_range");
|
||||||
|
RNA_def_property_ui_text(prop, "Active Dupli Object Index", "");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "dupli_object", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "dupli_object", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_pointer_sdna(prop, NULL, "dup_ob");
|
RNA_def_property_pointer_sdna(prop, NULL, "dup_ob");
|
||||||
RNA_def_property_struct_type(prop, "Object");
|
RNA_def_property_struct_type(prop, "Object");
|
||||||
@@ -2024,6 +2128,7 @@ void RNA_def_particle(BlenderRNA *brna)
|
|||||||
|
|
||||||
rna_def_child_particle(brna);
|
rna_def_child_particle(brna);
|
||||||
rna_def_particle(brna);
|
rna_def_particle(brna);
|
||||||
|
rna_def_particle_dupliweight(brna);
|
||||||
rna_def_particle_system(brna);
|
rna_def_particle_system(brna);
|
||||||
rna_def_particle_settings(brna);
|
rna_def_particle_settings(brna);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user