The revised patch from Leon for new particle effects.

New is that objects can have a force field, and Meshes can even deflect
(collide) particles. This is in a new sub-menu in Object buttons F7

The full instructions where on the web, Leon mailed it me and I will put
it in CMS tomorrow. For those who like to play with it now, here are demo
files:

http://download.blender.org/demo/test/

Quite some changes where in the integration though... so previous created
particle deflectors will not work. Changes to mention now are:
- gravity is renamed to 'force field'
- force field and deflector options are in Object now, not in Mesh
- the options also have its own struct, doesnt add to Object by default
- force fields are possible for all object types, but only work on center.
  So empty objects are typical for it.

Work to do:
- add draw method in 3d win to denote forcefield objects
- check on the UI (panel with different size?)
- add 'recalc' button in deflector panel
This commit is contained in:
2004-06-26 18:18:11 +00:00
parent 263d0823d3
commit e750478ce3
24 changed files with 2308 additions and 1598 deletions

View File

@@ -55,7 +55,7 @@ struct Particle *new_particle(struct PartEff *paf);
struct PartEff *give_parteff(struct Object *ob);
void where_is_particle(struct PartEff *paf, struct Particle *pa, float ctime, float *vec);
void particle_tex(struct MTex *mtex, struct PartEff *paf, float *co, float *no);
void make_particle_keys(int depth, int nr, struct PartEff *paf, struct Particle *part, float *force, int deform, struct MTex *mtex);
void make_particle_keys(int depth, int nr, struct PartEff *paf, struct Particle *part, float *force, int deform, struct MTex *mtex, unsigned int par_layer);
void init_mv_jit(float *jit, int num,float seed2);
void give_mesh_mvert(struct Mesh *me, int nr, float *co, short *no,float seed2);
void build_particle_system(struct Object *ob);

View File

@@ -1,4 +1,4 @@
/* effect.c
/* effect.c
*
*
* $Id$
@@ -47,6 +47,7 @@
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
#include "DNA_lattice_types.h"
#include "DNA_ipo_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -60,11 +61,14 @@
#include "BKE_key.h"
#include "BKE_ipo.h"
#include "BKE_screen.h"
#include "BKE_main.h"
#include "BKE_blender.h"
#include "BKE_object.h"
#include "BKE_displist.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "BKE_action.h"
#include "BKE_constraint.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -303,7 +307,6 @@ void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec)
}
void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
{
extern float Tin, Tr, Tg, Tb;
@@ -322,6 +325,7 @@ void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
no[0]+= (Tr-0.5f)*paf->texfac;
no[1]+= (Tg-0.5f)*paf->texfac;
no[2]+= (Tb-0.5f)*paf->texfac;
//printf("Test %f %f %f \n", Tr, Tg, Tb);
}
else { /* PAF_TEXGRAD */
@@ -343,51 +347,486 @@ void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
}
}
void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex)
static float linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3])
{
float p[3], s[3], d[3], e1[3], e2[3], q[3];
float a, f, u, v, t;
VecSubf(e1, v1, v0);
VecSubf(e2, v2, v0);
VecSubf(d, p2, p1);
Crossf(p, d, e2);
a = Inpf(e1, p);
if ((a > -0.000001) && (a < 0.000001)) return -1;
f = 1/a;
VecSubf(s, p1, v0);
u = f * Inpf(s, p);
if ((u < 0.0)||(u > 1.0)) return -1;
Crossf(q, s, e1);
t = f * Inpf(e2, q);
if ((t < 0.0)||(t > 1.0)) return -1;
v = f * Inpf(d, q);
if ((v < 0.0)||((u + v) > 1.0)) return -1;
return t;
}
static void get_forcefield(float opco[], float force[], float cur_time, unsigned int par_layer)
{
/* Particle gravity code */
/* Modifies the force on a particle according to its */
/* distance from mesh vertices set to attract / repel */
Object *ob;
Base *base;
float vect_to_vert[3];
float f_force, distance;
float obloc[3];
float force_val, ffall_val;
short cur_frame;
/* Cycle through objects, get total of (1/(gravity_strength * dist^gravity_power)) */
/* Check for min distance here? */
base = G.scene->base.first;
while (base) {
if(base->lay & par_layer) {
ob= base->object;
if(ob->pd && ob->pd->forcefield) {
/* Need to set r.cfra for paths (investigate, ton) */
cur_frame = G.scene->r.cfra;
G.scene->r.cfra = (short)cur_time;
where_is_object_time(ob, cur_time);
G.scene->r.cfra = cur_frame;
/* only use center of object */
obloc[0] = ob->obmat[3][0];
obloc[1] = ob->obmat[3][1];
obloc[2] = ob->obmat[3][2];
/* Get IPO force strength and fall off values here */
if (has_ipo_code(ob->ipo, OB_PD_FSTR))
force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
else
force_val = ob->pd->f_strength;
if (has_ipo_code(ob->ipo, OB_PD_FFALL))
ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
else
ffall_val = ob->pd->f_power;
/* Now calculate the gravitational force */
VecSubf(vect_to_vert, obloc, opco);
distance = Normalise(vect_to_vert);
/* Limit minimum distance to vertex so that */
/* the force is not too big */
if (distance < 0.001) distance = 0.001;
f_force = (force_val)*(1/(1000 * pow((double)distance, (double)ffall_val)));
force[0] += (vect_to_vert[0] * f_force );
force[1] += (vect_to_vert[1] * f_force );
force[2] += (vect_to_vert[2] * f_force );
}
}
base = base->next;
}
}
static int get_deflection(float opco[3], float npco[3], float opno[3],
float npno[3], float life, float force[3], int def_depth,
float cur_time, unsigned int par_layer, int *last_object,
int *last_face, int *same_face)
{
/* Particle deflection code */
/* The code is in two sections: the first part checks whether a particle has */
/* intersected a face of a deflector mesh, given its old and new co-ords, opco and npco */
/* and which face it hit first */
/* The second part calculates the new co-ordinates given that collision and updates */
/* the new co-ordinates accordingly */
Base *base;
Object *ob, *deflection_object = NULL;
Mesh *def_mesh;
MFace *mface, *deflection_face = NULL;
float *v1, *v2, *v3, *v4;
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3];
float dv1[3], dv2[3], dv3[3];
float vect_to_int[3], refl_vel[3];
float d_intersect_co[3], d_intersect_vect[3], d_nvect[3], d_i_co_above[3];
float forcec[3];
float k_point3, dist_to_plane;
float first_dist, ref_plane_mag;
float dk_plane=0, dk_point1=0;
float icalctop, icalcbot, n_mag;
float mag_iv, x_m,y_m,z_m;
float damping, perm_thresh;
float perm_val, rdamp_val;
int a, deflected=0, deflected_now=0;
float t, min_t;
float mat[3][3], obloc[3];
short cur_frame;
float time_before, time_after;
float force_mag_norm;
int d_object=0, d_face=0, ds_object=0, ds_face=0;
first_dist = 200000;
min_t = 200000;
/* The first part of the code, finding the first intersected face*/
base= G.scene->base.first;
while (base) {
/*Only proceed for mesh object in same layer */
if(base->object->type==OB_MESH && (base->lay & par_layer)) {
ob= base->object;
/* only with deflecting set */
if(ob->pd && ob->pd->deflect) {
def_mesh= ob->data;
d_object = d_object + 1;
d_face = d_face + 1;
mface= def_mesh->mface;
a = def_mesh->totface;
/*Find out where the object is at this time*/
cur_frame = G.scene->r.cfra;
G.scene->r.cfra = (short)cur_time;
where_is_object_time(ob, cur_time);
G.scene->r.cfra = cur_frame;
/*Pass the values from ob->obmat to mat*/
/*and the location values to obloc */
Mat3CpyMat4(mat,ob->obmat);
obloc[0] = ob->obmat[3][0];
obloc[1] = ob->obmat[3][1];
obloc[2] = ob->obmat[3][2];
while (a--) {
/* Calculate the global co-ordinates of the vertices*/
v1= (def_mesh->mvert+(mface->v1))->co;
v2= (def_mesh->mvert+(mface->v2))->co;
v3= (def_mesh->mvert+(mface->v3))->co;
v4= (def_mesh->mvert+(mface->v4))->co;
VECCOPY(nv1, v1);
VECCOPY(nv2, v2);
VECCOPY(nv3, v3);
VECCOPY(nv4, v4);
/*Apply the objects deformation matrix*/
Mat3MulVecfl(mat, nv1);
Mat3MulVecfl(mat, nv2);
Mat3MulVecfl(mat, nv3);
Mat3MulVecfl(mat, nv4);
VecAddf(nv1, nv1, obloc);
VecAddf(nv2, nv2, obloc);
VecAddf(nv3, nv3, obloc);
VecAddf(nv4, nv4, obloc);
deflected_now = 0;
t = - 1;
t = linetriangle(opco, npco, nv1, nv2, nv3);
if ((t > 0)&&(t < min_t)) {
deflected = 1;
deflected_now = 1;
}
else if (mface->v4) {
t = linetriangle(opco, npco, nv1, nv3, nv4);
if ((t > 0)&&(t < min_t)) {
deflected = 1;
deflected_now = 2;
}
}
if ((deflected_now > 0)&&(t < min_t)) {
min_t = t;
ds_object = d_object;
ds_face = d_face;
deflection_object = ob;
deflection_face = mface;
if (deflected_now==1) {
VECCOPY(dv1, nv1);
VECCOPY(dv2, nv2);
VECCOPY(dv3, nv3);
}
else {
VECCOPY(dv1, nv1);
VECCOPY(dv2, nv3);
VECCOPY(dv3, nv4);
}
}
mface++;
}
}
}
base = base->next;
}
/* Here's the point to do the permeability calculation */
/* Set deflected to 0 if a random number is below the value */
/* Get the permeability IPO here*/
if (deflected) {
if (has_ipo_code(deflection_object->ipo, OB_PD_PERM))
perm_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_PERM, cur_time);
else
perm_val = deflection_object->pd->pdef_perm;
perm_thresh = BLI_drand() - perm_val;
if (perm_thresh < 0 ) {
deflected = 0;
}
}
/* Now for the second part of the deflection code - work out the new speed */
/* and position of the particle if a collision occurred */
if (deflected) {
VecSubf(edge1, dv1, dv2);
VecSubf(edge2, dv3, dv2);
Crossf(d_nvect, edge2, edge1);
n_mag = Normalise(d_nvect);
dk_plane = Inpf(d_nvect, nv1);
dk_point1 = Inpf(d_nvect,opco);
VecSubf(d_intersect_vect, npco, opco);
d_intersect_co[0] = opco[0] + (min_t * (npco[0] - opco[0]));
d_intersect_co[1] = opco[1] + (min_t * (npco[1] - opco[1]));
d_intersect_co[2] = opco[2] + (min_t * (npco[2] - opco[2]));
d_i_co_above[0] = (d_intersect_co[0] + (0.001 * d_nvect[0]));
d_i_co_above[1] = (d_intersect_co[1] + (0.001 * d_nvect[1]));
d_i_co_above[2] = (d_intersect_co[2] + (0.001 * d_nvect[2]));
mag_iv = Normalise(d_intersect_vect);
VECCOPY(npco, d_intersect_co);
VecSubf(vect_to_int, opco, d_intersect_co);
first_dist = Normalise(vect_to_int);
/* Work out the lengths of time before and after collision*/
time_before = (life*(first_dist / (mag_iv)));
time_after = (life*((mag_iv - first_dist) / (mag_iv)));
/* We have to recalculate what the speed would have been at the */
/* point of collision, not the key frame time */
npno[0]= opno[0] + time_before*force[0];
npno[1]= opno[1] + time_before*force[1];
npno[2]= opno[2] + time_before*force[2];
/* Reflect the speed vector in the face */
x_m = (2 * npno[0] * d_nvect[0]);
y_m = (2 * npno[1] * d_nvect[1]);
z_m = (2 * npno[2] * d_nvect[2]);
refl_vel[0] = npno[0] - (d_nvect[0] * (x_m + y_m + z_m));
refl_vel[1] = npno[1] - (d_nvect[1] * (x_m + y_m + z_m));
refl_vel[2] = npno[2] - (d_nvect[2] * (x_m + y_m + z_m));
/*A random variation in the damping factor........ */
/*Get the IPO values for damping here*/
if (has_ipo_code(deflection_object->ipo, OB_PD_SDAMP))
damping = IPO_GetFloatValue(deflection_object->ipo, OB_PD_SDAMP, cur_time);
else
damping = deflection_object->pd->pdef_damp;
if (has_ipo_code(deflection_object->ipo, OB_PD_RDAMP))
rdamp_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_RDAMP, cur_time);
else
rdamp_val = deflection_object->pd->pdef_rdamp;
damping = damping + ((1 - damping) * (BLI_drand()*rdamp_val));
damping = damping * damping;
ref_plane_mag = Inpf(refl_vel,d_nvect);
if (damping > 0.999) damping = 0.999;
/* Now add in the damping force - only damp in the direction of */
/* the faces normal vector */
npno[0] = (refl_vel[0] - (d_nvect[0] * ref_plane_mag * damping));
npno[1] = (refl_vel[1] - (d_nvect[1] * ref_plane_mag * damping));
npno[2] = (refl_vel[2] - (d_nvect[2] * ref_plane_mag * damping));
/* Now reset opno */
VECCOPY(opno,npno);
VECCOPY(forcec, force);
/* If the particle has bounced more than four times on the same */
/* face within this cycle (depth > 4, same face > 4 ) */
/* Then set the force to be only that component of the force */
/* in the same direction as the face normal */
/* i.e. subtract the component of the force in the direction */
/* of the face normal from the actual force */
if ((ds_object == *last_object) && (ds_face == *last_face)) {
/* Increment same_face */
*same_face = *same_face + 1;
if ((*same_face > 3) && (def_depth > 3)) {
force_mag_norm = Inpf(forcec, d_nvect);
forcec[0] = forcec[0] - (d_nvect[0] * force_mag_norm);
forcec[1] = forcec[1] - (d_nvect[1] * force_mag_norm);
forcec[2] = forcec[2] - (d_nvect[2] * force_mag_norm);
}
}
else *same_face = 1;
*last_object = ds_object;
*last_face = ds_face;
/* We have the particles speed at the point of collision */
/* Now we want the particles speed at the current key frame */
npno[0]= npno[0] + time_after*forcec[0];
npno[1]= npno[1] + time_after*forcec[1];
npno[2]= npno[2] + time_after*forcec[2];
/* Now we have to recalculate pa->co for the remainder*/
/* of the time since the intersect*/
npco[0]= npco[0] + time_after*npno[0];
npco[1]= npco[1] + time_after*npno[1];
npco[2]= npco[2] + time_after*npno[2];
/* And set the old co-ordinates back to the point just above the intersection */
VECCOPY(opco, d_i_co_above);
/* Finally update the time */
life = time_after;
cur_time += time_before;
/* The particle may have fallen through the face again by now!!*/
/* So check if the particle has changed sides of the plane compared*/
/* the co-ordinates at the last keyframe*/
/* But only do this as a last resort, if we've got to the end of the */
/* number of collisions allowed */
if (def_depth==9) {
k_point3 = Inpf(d_nvect,npco);
if (((dk_plane > k_point3) && (dk_plane < dk_point1))||((dk_plane < k_point3) && (dk_plane > dk_point1))) {
/* Yup, the pesky particle may have fallen through a hole!!! */
/* So we'll cheat a bit and move the particle along the normal vector */
/* until it's just the other side of the plane */
icalctop = (dk_plane - d_nvect[0]*npco[0] - d_nvect[1]*npco[1] - d_nvect[2]*npco[2]);
icalcbot = (d_nvect[0]*d_nvect[0] + d_nvect[1]*d_nvect[1] + d_nvect[2]*d_nvect[2]);
dist_to_plane = icalctop / icalcbot;
/* Now just increase the distance a little to place */
/* the point the other side of the plane */
dist_to_plane *= 1.1;
npco[0]= npco[0] + (dist_to_plane * d_nvect[0]);
npco[1]= npco[1] + (dist_to_plane * d_nvect[1]);
npco[2]= npco[2] + (dist_to_plane * d_nvect[2]);
}
}
}
return deflected;
}
void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex, unsigned int par_layer)
{
Particle *pa, *opa = NULL;
float damp, deltalife;
int b, rt1, rt2;
float damp, deltalife, life;
float cur_time;
float opco[3], opno[3], npco[3], npno[3], new_force[3];
int b, rt1, rt2, deflected, deflection, finish_defs, def_count;
int last_ob, last_fc, same_fc;
damp= 1.0f-paf->damp;
pa= part;
/* start speed: random */
if(paf->randfac!=0.0) {
pa->no[0]+= (float)(paf->randfac*( BLI_drand() -0.5));
pa->no[1]+= (float)(paf->randfac*( BLI_drand() -0.5));
pa->no[2]+= (float)(paf->randfac*( BLI_drand() -0.5));
}
/* start speed: texture */
if(mtex && paf->texfac!=0.0) {
particle_tex(mtex, paf, pa->co, pa->no);
/* particle_tex(mtex, paf, pa->co, pa->no); */
}
if(paf->totkey>1) deltalife= pa->lifetime/(paf->totkey-1);
else deltalife= pa->lifetime;
opa= pa;
pa++;
b= paf->totkey-1;
while(b--) {
/* new time */
pa->time= opa->time+deltalife;
/* set initial variables */
opco[0] = opa->co[0];
opco[1] = opa->co[1];
opco[2] = opa->co[2];
new_force[0] = force[0];
new_force[1] = force[1];
new_force[2] = force[2];
/* Check force field */
cur_time = pa->time;
get_forcefield(opco, new_force, cur_time, par_layer);
/* new location */
pa->co[0]= opa->co[0] + deltalife*opa->no[0];
pa->co[1]= opa->co[1] + deltalife*opa->no[1];
pa->co[2]= opa->co[2] + deltalife*opa->no[2];
/* new speed */
pa->no[0]= opa->no[0] + deltalife*force[0];
pa->no[1]= opa->no[1] + deltalife*force[1];
pa->no[2]= opa->no[2] + deltalife*force[2];
pa->no[0]= opa->no[0] + deltalife*new_force[0];
pa->no[1]= opa->no[1] + deltalife*new_force[1];
pa->no[2]= opa->no[2] + deltalife*new_force[2];
/* Particle deflection code */
deflection = 0;
finish_defs = 1;
def_count = 0;
VECCOPY(opno, opa->no);
VECCOPY(npco, pa->co);
VECCOPY(npno, pa->no);
life = deltalife;
cur_time -= deltalife;
last_ob = -1;
last_fc = -1;
same_fc = 0;
/* First call the particle deflection check for the particle moving */
/* between the old co-ordinates and the new co-ordinates */
/* If a deflection occurs, call the code again, this time between the */
/* intersection point and the updated new co-ordinates */
/* Bail out if we've done the calculation 10 times - this seems ok */
/* for most scenes I've tested */
while (finish_defs) {
deflected = get_deflection(opco, npco, opno, npno, life, new_force,
def_count, cur_time, par_layer,
&last_ob, &last_fc, &same_fc);
if (deflected) {
def_count = def_count + 1;
deflection = 1;
if (def_count==10) finish_defs = 0;
}
else {
finish_defs = 0;
}
}
/* Only update the particle positions and speed if we had a deflection */
if (deflection) {
pa->co[0] = npco[0];
pa->co[1] = npco[1];
pa->co[2] = npco[2];
pa->no[0] = npno[0];
pa->no[1] = npno[1];
pa->no[2] = npno[2];
}
/* speed: texture */
if(mtex && paf->texfac!=0.0) {
particle_tex(mtex, paf, pa->co, pa->no);
particle_tex(mtex, paf, opa->co, opa->no);
}
if(damp!=1.0) {
pa->no[0]*= damp;
@@ -395,6 +834,8 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *
pa->no[2]*= damp;
}
opa= pa;
pa++;
/* opa is used later on too! */
@@ -428,8 +869,8 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *
pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
}
pa->mat_nr= paf->mat[depth];
make_particle_keys(depth+1, b, paf, pa, force, deform, mtex);
make_particle_keys(depth+1, b, paf, pa, force, deform, mtex, par_layer);
}
}
}
@@ -495,14 +936,14 @@ void give_mesh_mvert(Mesh *me, int nr, float *co, short *no, float seed2)
VECCOPY(no, mvert->no);
}
else {
nr-= me->totvert;
if(jit==0) {
jitlevel= nr/me->totface;
if(jitlevel==0) jitlevel= 1;
if(jitlevel>100) jitlevel= 100;
jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
init_mv_jit(jit, jitlevel,seed2);
@@ -515,7 +956,7 @@ void give_mesh_mvert(Mesh *me, int nr, float *co, short *no, float seed2)
mface= me->mface;
mface+= curface;
v1= (me->mvert+(mface->v1))->co;
v2= (me->mvert+(mface->v2))->co;
n1= (me->mvert+(mface->v1))->no;
@@ -563,31 +1004,32 @@ void build_particle_system(Object *ob)
MVert *mvert;
MTex *mtexmove=0;
Material *ma;
int armature_parent;
float framelenont, ftime, dtime, force[3], imat[3][3], vec[3];
float fac, prevobmat[4][4], sfraont, co[3];
int deform=0, a, cur, cfraont, cfralast, totpart;
int deform=0, a, b, c, cur, cfraont, cfralast, totpart;
short no[3];
if(ob->type!=OB_MESH) return;
me= ob->data;
if(me->totvert==0) return;
ma= give_current_material(ob, 1);
if(ma) {
mtexmove= ma->mtex[7];
}
paf= give_parteff(ob);
if(paf==0) return;
waitcursor(1);
disable_speed_curve(1);
/* generate all particles */
if(paf->keys) MEM_freeN(paf->keys);
paf->keys= 0;
new_particle(paf);
new_particle(paf);
cfraont= G.scene->r.cfra;
cfralast= -1000;
@@ -595,7 +1037,7 @@ void build_particle_system(Object *ob)
G.scene->r.framelen= 1.0;
sfraont= ob->sf;
ob->sf= 0.0;
/* mult generations? */
totpart= paf->totpart;
for(a=0; a<PAF_MAXMULT; a++) {
@@ -608,7 +1050,7 @@ void build_particle_system(Object *ob)
ftime= paf->sta;
dtime= (paf->end - paf->sta)/totpart;
/* remember full hierarchy */
par= ob;
while(par) {
@@ -619,13 +1061,20 @@ void build_particle_system(Object *ob)
/* set it all at first frame */
G.scene->r.cfra= cfralast= (int)floor(ftime);
par= ob;
armature_parent = 0;
while(par) {
/* do_ob_ipo(par); */
do_ob_key(par);
/* Just checking whether theres an armature in the */
/* parent chain of the emitter, so we know whether */
/* to recalculate the armatures */
if(par->type==OB_ARMATURE) {
armature_parent = 1;
}
par= par->parent;
}
do_mat_ipo(ma);
if((paf->flag & PAF_STATIC)==0) {
where_is_object(ob);
Mat4CpyMat4(prevobmat, ob->obmat);
@@ -649,16 +1098,28 @@ void build_particle_system(Object *ob)
/* init */
give_mesh_mvert(me, totpart, co, no,paf->seed);
printf("\n");
printf("Calculating particles......... \n");
for(a=0; a<totpart; a++, ftime+=dtime) {
pa= new_particle(paf);
pa->time= ftime;
c = totpart/100;
if (c==0){
c = 1;
}
b=(a%c);
if (b==0) {
printf("\r Particle: %d / %d ", a, totpart);
}
/* set ob at correct time */
if((paf->flag & PAF_STATIC)==0) {
cur= (int)floor(ftime) + 1 ; /* + 1 has a reason: (obmat/prevobmat) otherwise comet-tails start too late */
if(cfralast != cur) {
G.scene->r.cfra= cfralast= cur;
@@ -666,6 +1127,12 @@ void build_particle_system(Object *ob)
/* added later: blur? */
bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
/* Update the armatures */
if (armature_parent) {
do_all_actions();
rebuild_all_armature_displists();
}
par= ob;
while(par) {
/* do_ob_ipo(par); */
@@ -726,9 +1193,11 @@ void build_particle_system(Object *ob)
}
pa->mat_nr= 1;
make_particle_keys(0, a, paf, pa, force, deform, mtexmove);
make_particle_keys(0, a, paf, pa, force, deform, mtexmove, ob->lay);
}
printf("\r Particle: %d / %d \n", totpart, totpart);
if(deform) end_latt_deform();
/* restore */
@@ -736,6 +1205,11 @@ void build_particle_system(Object *ob)
G.scene->r.framelen= framelenont;
give_mesh_mvert(0, 0, 0, 0,paf->seed);
/*Restore armature settings*/
if (armature_parent) {
do_all_actions();
rebuild_all_armature_displists();
}
/* put hierarchy back */
par= ob;

View File

@@ -1,4 +1,4 @@
/* ipo.c
/* ipo.c
*
* $Id$
*
@@ -55,6 +55,7 @@
#include "DNA_texture_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_action_types.h"
@@ -72,6 +73,7 @@
#include "BKE_blender.h"
#include "BKE_ipo.h"
#include "BKE_constraint.h"
#include "BKE_mesh.h"
#define SMALL -1.0e-10
@@ -88,7 +90,8 @@ int ob_ar[OB_TOTIPO]= {
OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z,
OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z,
OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z,
OB_LAY, OB_TIME, OB_EFF_X, OB_EFF_Y, OB_EFF_Z, OB_COL_A
OB_LAY, OB_TIME, OB_EFF_X, OB_EFF_Y, OB_EFF_Z, OB_COL_A,
OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM
};
int ac_ar[AC_TOTIPO]= {
@@ -100,7 +103,7 @@ int ac_ar[AC_TOTIPO]= {
int ma_ar[MA_TOTIPO]= {
MA_COL_R, MA_COL_G, MA_COL_B,
MA_SPEC_R, MA_SPEC_G, MA_SPEC_B,
MA_MIR_R, MA_MIR_G, MA_MIR_B,
MA_MIR_R, MA_MIR_G, MA_MIR_B,
MA_REF, MA_ALPHA, MA_EMIT, MA_AMB,
MA_SPEC, MA_HARD, MA_SPTR, MA_ANG,
MA_MODE, MA_HASIZE,
@@ -205,7 +208,7 @@ Ipo *copy_ipo(Ipo *ipo)
ipon= copy_libblock(ipo);
duplicatelist(&(ipon->curve), &(ipo->curve));
icu= ipon->curve.first;
while(icu) {
icu->bezt= MEM_dupallocN(icu->bezt);
@@ -701,7 +704,7 @@ float eval_icu(IpoCurve *icu, float ipotime)
prevbezt+= a;
dx= ipotime-prevbezt->vec[1][0];
fac= prevbezt->vec[2][0]-prevbezt->vec[1][0];
if(fac!=0) {
fac= (prevbezt->vec[2][1]-prevbezt->vec[1][1])/fac;
cvalue= prevbezt->vec[1][1]+fac*dx;
@@ -907,11 +910,10 @@ void *give_mtex_poin(MTex *mtex, int adrcode )
void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
{
void *poin= 0;
void *poin= NULL;
Object *ob;
Material *ma;
MTex *mtex;
Ika *ika= 0;
Lamp *la;
Sequence *seq;
World *wo;
@@ -921,13 +923,10 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
*type= IPO_FLOAT;
if( GS(id->name)==ID_OB) {
ob= (Object *)id;
if(ob->type==OB_IKA) ika= ob->data;
switch(icu->adrcode) {
case OB_LOC_X:
poin= &(ob->loc[0]); break;
@@ -967,25 +966,37 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(ob->dsize[1]); break;
case OB_DSIZE_Z:
poin= &(ob->dsize[2]); break;
case OB_LAY:
poin= &(ob->lay); *type= IPO_INT_BIT; break;
case OB_EFF_X: /* OB_COL_R */
if(ika) poin= &(ika->effg[0]);
else poin= &(ob->col[0]);
case OB_COL_R:
poin= &(ob->col[0]);
break;
case OB_EFF_Y: /* OB_COL_G */
if(ika) poin= &(ika->effg[1]);
else poin= &(ob->col[1]);
case OB_COL_G:
poin= &(ob->col[1]);
break;
case OB_EFF_Z: /* OB_COL_B */
if(ika) poin= &(ika->effg[2]);
else poin= &(ob->col[2]);
case OB_COL_B:
poin= &(ob->col[2]);
break;
case OB_COL_A:
poin= &(ob->col[3]);
break;
case OB_PD_FSTR:
if(ob->pd) poin= &(ob->pd->f_strength);
break;
case OB_PD_FFALL:
if(ob->pd) poin= &(ob->pd->f_power);
break;
case OB_PD_SDAMP:
if(ob->pd) poin= &(ob->pd->pdef_damp);
break;
case OB_PD_RDAMP:
if(ob->pd) poin= &(ob->pd->pdef_rdamp);
break;
case OB_PD_PERM:
if(ob->pd) poin= &(ob->pd->pdef_perm);
break;
}
}
else if (GS(id->name)==ID_AC){
@@ -1808,6 +1819,11 @@ void make_cfra_list(Ipo *ipo, ListBase *elems)
case OB_SIZE_X:
case OB_SIZE_Y:
case OB_SIZE_Z:
case OB_PD_FSTR:
case OB_PD_FFALL:
case OB_PD_SDAMP:
case OB_PD_RDAMP:
case OB_PD_PERM:
bezt= icu->bezt;
if(bezt) {
a= icu->totvert;

View File

@@ -196,6 +196,8 @@ void free_object(Object *ob)
freedisplist(&ob->disp);
BPY_free_scriptlink(&ob->scriptlink);
if(ob->pd) MEM_freeN(ob->pd);
}
void unlink_object(Object *ob)
@@ -727,6 +729,8 @@ Object *copy_object(Object *ob)
if (actcon)
obn->activecon = actcon;
if(ob->pd) obn->pd= MEM_dupallocN(ob->pd);
/* increase user numbers */
id_us_plus((ID *)obn->data);
id_us_plus((ID *)obn->ipo);

View File

@@ -2204,7 +2204,7 @@ static void direct_link_object(FileData *fd, Object *ob)
paf= paf->next;
}
link_list(fd, &ob->network);
ob->pd= newdataadr(fd, ob->pd);
link_list(fd, &ob->prop);
prop= ob->prop.first;

View File

@@ -649,6 +649,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
write_constraints(wd, &ob->constraints);
write_constraint_channels(wd, &ob->constraintChannels);
write_nlastrips(wd, &ob->nlastrips);
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
}
ob= ob->id.next;
}

View File

@@ -57,6 +57,7 @@ extern void redraw_test_buttons(struct Base *new);
#define BUTS_SCRIPT 11
#define BUTS_SOUND 12
#define BUTS_CONSTRAINT 13
#define BUTS_EFFECTS 14
/* warning: the values of these defines are used in sbuts->tabs[7] */
/* buts->mainb new */
@@ -80,6 +81,9 @@ extern void redraw_test_buttons(struct Base *new);
#define TAB_SHADING_WORLD 3
#define TAB_SHADING_LAMP 4
#define TAB_OBJECT_OBJECT 0
#define TAB_OBJECT_EFFECTS 1
/* buts->scaflag */
#define BUTS_SENS_SEL 1
#define BUTS_SENS_ACT 2

View File

@@ -26,7 +26,7 @@
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -60,7 +60,7 @@ typedef enum {
ICON_ORTHO,
ICON_PERSP,
ICON_CAMERA,
ICON_BLANK1,
ICON_EFFECTS,
ICON_BBOX,
ICON_WIRE,
ICON_SOLID,
@@ -89,7 +89,7 @@ typedef enum {
ICON_POSE_HLT,
ICON_BORDERMOVE,
ICON_MAYBE_ITS_A_LASSO,
ICON_BLANK6,
ICON_BLANK1,
ICON_ROTATE,
ICON_CURSOR,
ICON_ROTATECOLLECTION,
@@ -101,6 +101,8 @@ typedef enum {
ICON_BLANK11,
ICON_BLANK12,
ICON_DOTSUP,
ICON_DOTSDOWN,
ICON_MENU_PANEL,

View File

@@ -66,7 +66,7 @@ typedef struct EditIpo {
/* ******************** */
#define OB_TOTIPO 24
#define OB_TOTIPO 29
#define OB_LOC_X 1
#define OB_LOC_Y 2
@@ -102,6 +102,11 @@ typedef struct EditIpo {
#define OB_COL_B 23
#define OB_COL_A 24
#define OB_PD_GRAV 25
#define OB_PD_GFALL 26
#define OB_PD_SDAMP 27
#define OB_PD_RDAMP 28
#define OB_PD_PERM 29
/* ******************** */

View File

@@ -63,6 +63,9 @@ extern void object_panels(void);
extern void do_object_panels(unsigned short event);
extern void do_constraintbuts(unsigned short event);
/* effects */
extern void effects_panels(void);
extern void do_effects_panels(unsigned short event);
/* editing */
extern void editing_panels(void);
@@ -206,15 +209,6 @@ void butspace_context_switch(SpaceButs *buts, struct Base *new);
#define B_RECALCPATH 1401
#define B_AUTOTIMEOFS 1403
#define B_FRAMEMAP 1404
#define B_NEWEFFECT 1405
#define B_PREVEFFECT 1406
#define B_NEXTEFFECT 1407
#define B_CHANGEEFFECT 1408
#define B_CALCEFFECT 1409
#define B_DELEFFECT 1410
#define B_RECALCAL 1411
#define B_PRINTSPEED 1413
#define B_PRINTLEN 1414
@@ -342,13 +336,6 @@ enum {
#define B_MAKESTICKY 2082
#define B_MAKEVERTCOL 2083
#define B_CHROMADEPTH 2084
#define B_ISDEFLECTOR 2085
#define B_PDEFDAMPING 2086
#define B_GRAVITY 2087
#define B_GRAVSTRENGTH 2088
#define B_GRAVPOWER 2089
#define B_PDEFRDAMP 2090
#define B_PDEFPERM 2091
/* *********************** */
#define B_CURVEBUTS 2200
@@ -554,6 +541,20 @@ enum {
B_UVAUTO_ALIGNX,
B_UVAUTO_ALIGNY
};
#define B_EFFECTSBUTS 3500
#define B_AUTOTIMEOFS 3403
#define B_FRAMEMAP 3404
#define B_NEWEFFECT 3405
#define B_PREVEFFECT 3406
#define B_NEXTEFFECT 3407
#define B_CHANGEEFFECT 3408
#define B_CALCEFFECT 3409
#define B_DELEFFECT 3410
#define B_RECALCAL 3411
#define B_RECALC_DEFL 3412
/* *********************** */
/* *********************** */

View File

@@ -65,7 +65,7 @@ typedef struct EditIpo {
/* ******************** */
#define OB_TOTIPO 24
#define OB_TOTIPO 29
#define OB_LOC_X 1
#define OB_LOC_Y 2
@@ -101,6 +101,11 @@ typedef struct EditIpo {
#define OB_COL_B 23
#define OB_COL_A 24
#define OB_PD_GRAV 25
#define OB_PD_GFALL 26
#define OB_PD_SDAMP 27
#define OB_PD_RDAMP 28
#define OB_PD_PERM 29
/* ******************** */

View File

@@ -218,6 +218,7 @@
#define REDRAWBUTSLOGIC 0x401B
#define REDRAWBUTSSHADING 0x401C
#define REDRAWBUTSGAME 0x401D
#define REDRAWBUTSEFFECTS 0x401D
#define REDRAWINFO 0x4021
#define RENDERPREVIEW 0x4022

View File

@@ -65,7 +65,7 @@ typedef short IPO_Channel;
/* ******************** */
#define OB_TOTIPO 24
#define OB_TOTIPO 29
#define OB_LOC_X 1
#define OB_LOC_Y 2
@@ -101,6 +101,12 @@ typedef short IPO_Channel;
#define OB_COL_B 23
#define OB_COL_A 24
#define OB_PD_FSTR 25
#define OB_PD_FFALL 26
#define OB_PD_SDAMP 27
#define OB_PD_RDAMP 28
#define OB_PD_PERM 29
/* ******************** */

View File

@@ -74,12 +74,12 @@ typedef struct Mesh {
struct MSticky *msticky;
struct Mesh *texcomesh;
float *orco;
struct OcInfo *oc; /* not written in file */
void *sumohandle;
int totvert, totface;
int texflag;
float loc[3];
float size[3];

View File

@@ -77,6 +77,19 @@ typedef struct LBuf {
struct Object **ob;
} LBuf;
typedef struct PartDeflect {
short deflect; /* Deflection flag - does mesh deflect particles*/
short forcefield; /* Force flag, do the vertices attract / repel particles ? */
float pdef_damp; /* Damping factor for particle deflection */
float pdef_rdamp; /* Random element of damping for deflection */
float pdef_perm; /* Chance of particle passing through mesh */
float f_strength; /* The strength of the force (+ or - ) */
float f_power; /* The power law - real gravitation is 2 (square) */
} PartDeflect;
typedef struct Object {
ID id;
@@ -179,6 +192,7 @@ typedef struct Object {
ListBase constraints;
ListBase nlastrips;
PartDeflect *pd; /* particle deflector/attractor/collision data */
struct Life *life;
LBuf lbuf;

View File

@@ -1912,7 +1912,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
rn= *re;
if( (rn->f & RAD_SHOOT)==0 ) { /* no shootelement */
if( rn->f & RAD_BACKFACE) Zvlnr= 0xFFFFFF;
if( rn->f & RAD_TWOSIDED) Zvlnr= a;
else if( rn->f & RAD_BACKFACE) Zvlnr= 0xFFFFFF;
else Zvlnr= a;
c1= hashlist_projectvert(rn->v1, hoco[0]);
@@ -1942,7 +1943,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
rf= vlr->radface;
if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */
if( rf->flag & RAD_BACKFACE) Zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
if( rf->flag & RAD_TWOSIDED) Zvlnr= totface;
else if( rf->flag & RAD_BACKFACE) Zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
else Zvlnr= totface;
c1= hashlist_projectvert(vlr->v1->co, hoco[0]);

File diff suppressed because it is too large Load Diff

View File

@@ -245,7 +245,7 @@ void do_butspace(unsigned short event)
if(buts->mainb==CONTEXT_EDITING) allqueue(REDRAWBUTSEDIT, curarea->win);
if(buts->mainb==CONTEXT_SCRIPT) allqueue(REDRAWBUTSSCRIPT, curarea->win);
if(buts->mainb==CONTEXT_LOGIC) allqueue(REDRAWBUTSLOGIC, curarea->win);
if (event <=50){
do_global_buttons2(event);
}
@@ -318,6 +318,10 @@ void do_butspace(unsigned short event)
else if(event<=B_UVAUTOCALCBUTS) {
do_uvautocalculationbuts(event);
}
else if(event<=B_EFFECTSBUTS) {
/*here we put the effects buttons do commands*/
do_effects_panels(event);
}
else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too
else if(event>REDRAWVIEW3D) allqueue(event, 0);
}
@@ -413,10 +417,14 @@ void drawbutspace(ScrArea *sa, void *spacedata)
break;
case CONTEXT_OBJECT:
/* no tabs */
object_panels();
break;
tab= sbuts->tab[CONTEXT_OBJECT];
if(tab== TAB_OBJECT_OBJECT) {
object_panels();
}
else if(tab == TAB_OBJECT_EFFECTS) {
effects_panels();
}
break;
case CONTEXT_SHADING:
tab= sbuts->tab[CONTEXT_SHADING];

View File

@@ -2499,9 +2499,9 @@ void editing_panels()
editing_panel_mesh_texface();
editing_panel_mesh_uvautocalculation();
}
if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) )
if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) ) {
editing_panel_mesh_paint();
}
}
break;

View File

@@ -971,9 +971,7 @@ void object_panel_draw(Object *ob)
void do_object_panels(unsigned short event)
{
Object *ob;
Base *base;
Effect *eff, *effn;
int type;
Effect *eff;
ob= OBACT;
@@ -983,116 +981,6 @@ void do_object_panels(unsigned short event)
calc_curvepath(OBACT);
allqueue(REDRAWVIEW3D, 0);
break;
case B_AUTOTIMEOFS:
auto_timeoffs();
break;
case B_FRAMEMAP:
G.scene->r.framelen= G.scene->r.framapto;
G.scene->r.framelen/= G.scene->r.images;
break;
case B_NEWEFFECT:
if(ob) {
if (BLI_countlist(&ob->effect)==MAX_EFFECT)
error("Unable to add: effect limit reached");
else
copy_act_effect(ob);
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_DELEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
effn= eff->next;
if(eff->flag & SELECT) {
BLI_remlink(&ob->effect, eff);
free_effect(eff);
break;
}
eff= effn;
}
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
break;
case B_NEXTEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->next) {
eff->flag &= ~SELECT;
eff->next->flag |= SELECT;
}
break;
}
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_PREVEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->prev) {
eff->flag &= ~SELECT;
eff->prev->flag |= SELECT;
}
break;
}
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_CHANGEEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type!=eff->buttype) {
BLI_remlink(&ob->effect, eff);
type= eff->buttype;
free_effect(eff);
eff= add_effect(type);
BLI_addtail(&ob->effect, eff);
}
break;
}
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
break;
case B_CALCEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type==EFF_PARTICLE) build_particle_system(ob);
else if(eff->type==EFF_WAVE) object_wave(ob);
}
eff= eff->next;
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_RECALCAL:
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
ob= base->object;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type==EFF_PARTICLE) build_particle_system(ob);
}
eff= eff->next;
}
}
base= base->next;
}
allqueue(REDRAWVIEW3D, 0);
break;
case B_PRINTSPEED:
ob= OBACT;
if(ob) {
@@ -1145,16 +1033,257 @@ void do_object_panels(unsigned short event)
}
void object_panel_effects(Object *ob)
static void object_panel_anim(Object *ob)
{
uiBlock *block;
char str[32];
block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX", 27,190,58,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-X", 124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-Y", 150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-Z", 177,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
uiBlockBeginAlign(block);
uiDefButC(block, ROW,REDRAWVIEW3D,"UpX", 226,190,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 274,190,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 297,190,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Draw Key", 25,160,70,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Draw Key Sel", 97,160,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
uiDefButC(block, TOG|BIT|7, REDRAWVIEW3D, "Powertrack", 180,160,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
uiDefButS(block, TOG|BIT|4, 0, "SlowPar", 261,160,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "DupliFrames", 24,128,88,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
uiDefButC(block, TOG|BIT|4, REDRAWVIEW3D, "DupliVerts", 114,128,82,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Rot", 200,128,31,19, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal");
uiDefButC(block, TOG|BIT|6, REDRAWVIEW3D, "No Speed", 234,128,82,19, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
uiBlockBeginAlign(block);
uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:", 24,105,141,19, &ob->dupsta, 1.0, 17999.0, 0, 0, "Specify startframe for Dupliframes");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:", 169,105,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd", 24,82,140,19, &ob->dupend, 1.0, 18000.0, 0, 0, "Specify endframe for Dupliframes");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff", 169,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|2, REDRAWALL, "Offs Ob", 23,51,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo");
uiDefButC(block, TOG|BIT|6, REDRAWALL, "Offs Par", 82,51,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent");
uiDefButC(block, TOG|BIT|7, REDRAWALL, "Offs Particle", 141,51,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 23,17,114,30, &ob->sf, -9000.0, 9000.0, 100, 0, "Specify an offset in frames");
uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 139,17,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 246,17,67,31, 0, 0, 0, 0, 0, "Print objectspeed");
uiBlockEndAlign(block);
sprintf(str, "%.4f", prspeed);
uiDefBut(block, LABEL, 0, str, 247,40,63,31, 0, 1.0, 0, 0, 0, "");
}
void object_panels()
{
Object *ob;
/* check context here */
ob= OBACT;
if(ob) {
if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
object_panel_anim(ob);
object_panel_draw(ob);
object_panel_constraint();
/* if(ob->type==OB_MESH) object_panel_effects(ob); */
uiClearButLock();
}
}
void do_effects_panels(unsigned short event)
{
Object *ob;
Base *base;
Effect *eff, *effn;
int type;
ob= OBACT;
switch(event) {
case B_AUTOTIMEOFS:
auto_timeoffs();
break;
case B_FRAMEMAP:
G.scene->r.framelen= G.scene->r.framapto;
G.scene->r.framelen/= G.scene->r.images;
break;
case B_NEWEFFECT:
if(ob) {
if (BLI_countlist(&ob->effect)==MAX_EFFECT)
error("Unable to add: effect limit reached");
else
copy_act_effect(ob);
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_DELEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
effn= eff->next;
if(eff->flag & SELECT) {
BLI_remlink(&ob->effect, eff);
free_effect(eff);
break;
}
eff= effn;
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_NEXTEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->next) {
eff->flag &= ~SELECT;
eff->next->flag |= SELECT;
}
break;
}
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_PREVEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->prev) {
eff->flag &= ~SELECT;
eff->prev->flag |= SELECT;
}
break;
}
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_CHANGEEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type!=eff->buttype) {
BLI_remlink(&ob->effect, eff);
type= eff->buttype;
free_effect(eff);
eff= add_effect(type);
BLI_addtail(&ob->effect, eff);
}
break;
}
eff= eff->next;
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_CALCEFFECT:
if(ob==0 || ob->type!=OB_MESH) break;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type==EFF_PARTICLE) build_particle_system(ob);
else if(eff->type==EFF_WAVE) object_wave(ob);
}
eff= eff->next;
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_RECALCAL:
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
ob= base->object;
eff= ob->effect.first;
while(eff) {
if(eff->flag & SELECT) {
if(eff->type==EFF_PARTICLE) build_particle_system(ob);
}
eff= eff->next;
}
}
base= base->next;
}
allqueue(REDRAWVIEW3D, 0);
break;
default:
if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
ob= OBACT;
if(ob) {
int a=B_SELEFFECT;
eff= ob->effect.first;
while(eff) {
if(event==a) eff->flag |= SELECT;
else eff->flag &= ~SELECT;
a++;
eff= eff->next;
}
allqueue(REDRAWBUTSOBJECT, 0);
}
}
}
}
/* Panel for particle interaction settings */
static void editing_panel_deflectors(Object *ob)
{
uiBlock *block;
block= uiNewBlock(&curarea->uiblocks, "editing_panel_deflectors", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Particle Interaction", "Effects", 0, 0, 190, 204)==0) return;
/* should become button, option? */
if(ob->pd==NULL) {
ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
/* and if needed, init here */
}
if(ob->pd) {
uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|0, B_DIFF, "Force field", 10,160,150,20, &ob->pd->forcefield, 0, 0, 0, 0, "Object center attracts or repels particles");
uiDefButF(block, NUM, B_DIFF, "Strength", 10,140,150,20, &ob->pd->f_strength, -100, 100, 0, 0, "Strength of force field");
uiDefButF(block, NUM, B_DIFF, "Fall-off", 10,120,150,20, &ob->pd->f_power, 0, 10, 0, 0, "Falloff power (real gravitational fallof = 2)");
/* only meshes collide now */
if(ob->type==OB_MESH) {
uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|0, B_DIFF, "Deflection",10,80,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
uiDefButF(block, NUM, B_DIFF, "Surface damping", 10,60,150,20, &ob->pd->pdef_damp, 0, 1, 0, 0, "Amount of damping during particle collision");
uiDefButF(block, NUM, B_DIFF, "Random damping", 10,40,150,20, &ob->pd->pdef_rdamp, 0, 1, 0, 0, "Random variation of damping");
uiDefButF(block, NUM, B_DIFF, "Permeability", 10,30,150,20, &ob->pd->pdef_perm, 0, 1, 0, 0, "Chance that the particle will pass through the mesh");
}
}
}
void effects_panel_effects(Object *ob)
{
Effect *eff;
uiBlock *block;
int a;
short x, y;
block= uiNewBlock(&curarea->uiblocks, "object_panel_effects", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Constraints", "Object");
if(uiNewPanel(curarea, block, "Effects", "Object", 640, 0, 418, 204)==0) return;
block= uiNewBlock(&curarea->uiblocks, "effect_panel_effects", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Effects", "Effects", 190, 0, 418, 204)==0) return;
/* EFFECTS */
@@ -1237,7 +1366,7 @@ void object_panel_effects(Object *ob)
uiDefButF(block, NUM, B_CALCEFFECT, "End:", 731,146,97,20, &paf->end, 1.0, 9000.0, 100, 0, "Specify the endframe");
}
uiDefButF(block, NUM, B_CALCEFFECT, "Life:", 831,146,88,20, &paf->lifetime, 1.0, 9000.0, 100, 0, "Specify the life span of the particles");
uiDefButI(block, NUM, B_CALCEFFECT, "Keys:", 922,146,80,20, &paf->totkey, 1.0, 32.0, 0, 0, "Specify the number of key positions");
uiDefButI(block, NUM, B_CALCEFFECT, "Keys:", 922,146,80,20, &paf->totkey, 1.0, 100.0, 0, 0, "Specify the number of key positions");
uiDefButS(block, NUM, B_REDR, "CurMul:", 550,124,91,20, &paf->curmult, 0.0, 3.0, 0, 0, "Multiply the particles");
uiDefButS(block, NUM, B_CALCEFFECT, "Mat:", 644,124,84,20, paf->mat+paf->curmult, 1.0, 8.0, 0, 0, "Specify the material used for the particles");
@@ -1287,57 +1416,8 @@ void object_panel_effects(Object *ob)
}
}
static void object_panel_anim(Object *ob)
{
uiBlock *block;
char str[32];
block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX", 27,190,58,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-X", 124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-Y", 150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
uiDefButC(block, ROW,REDRAWVIEW3D,"-Z", 177,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
uiBlockBeginAlign(block);
uiDefButC(block, ROW,REDRAWVIEW3D,"UpX", 226,190,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 274,190,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 297,190,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Draw Key", 25,160,70,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Draw Key Sel", 97,160,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
uiDefButC(block, TOG|BIT|7, REDRAWVIEW3D, "Powertrack", 180,160,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
uiDefButS(block, TOG|BIT|4, 0, "SlowPar", 261,160,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "DupliFrames", 24,128,88,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
uiDefButC(block, TOG|BIT|4, REDRAWVIEW3D, "DupliVerts", 114,128,82,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Rot", 200,128,31,19, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal");
uiDefButC(block, TOG|BIT|6, REDRAWVIEW3D, "No Speed", 234,128,82,19, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
uiBlockBeginAlign(block);
uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:", 24,105,141,19, &ob->dupsta, 1.0, 17999.0, 0, 0, "Specify startframe for Dupliframes");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:", 169,105,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd", 24,82,140,19, &ob->dupend, 1.0, 18000.0, 0, 0, "Specify endframe for Dupliframes");
uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff", 169,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|2, REDRAWALL, "Offs Ob", 23,51,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo");
uiDefButC(block, TOG|BIT|6, REDRAWALL, "Offs Par", 82,51,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent");
uiDefButC(block, TOG|BIT|7, REDRAWALL, "Offs Particle", 141,51,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 23,17,114,30, &ob->sf, -9000.0, 9000.0, 100, 0, "Specify an offset in frames");
uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 139,17,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 246,17,67,31, 0, 0, 0, 0, 0, "Print objectspeed");
uiBlockEndAlign(block);
sprintf(str, "%.4f", prspeed);
uiDefBut(block, LABEL, 0, str, 247,40,63,31, 0, 1.0, 0, 0, 0, "");
}
void object_panels()
void effects_panels()
{
Object *ob;
@@ -1346,12 +1426,11 @@ void object_panels()
if(ob) {
if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
object_panel_anim(ob);
object_panel_draw(ob);
object_panel_constraint();
if(ob->type==OB_MESH) object_panel_effects(ob);
editing_panel_deflectors(ob);
if(ob->type==OB_MESH) {
effects_panel_effects(ob);
}
uiClearButLock();
}
}

View File

@@ -2463,7 +2463,7 @@ int play_anim(int mode)
/* patch for very very old scenes */
if(SFRA==0) SFRA= 1;
if(EFRA==0) EFRA= 250;
if(SFRA>EFRA) return 0;
update_time();

View File

@@ -236,6 +236,21 @@ void getname_ob_ei(int nr, char *str, int colipo)
case OB_COL_A:
strcpy(str, "ColA");
break;
case OB_PD_FSTR:
strcpy(str, "FStreng");
break;
case OB_PD_FFALL:
strcpy(str, "FFall");
break;
case OB_PD_SDAMP:
strcpy(str, "Damping");
break;
case OB_PD_RDAMP:
strcpy(str, "RDamp");
break;
case OB_PD_PERM:
strcpy(str, "Perm");
break;
default:
str[0]= 0;
}
@@ -3789,13 +3804,40 @@ void common_insertkey()
insertkey(id, map+MAP_SIZE_Y);
insertkey(id, map+MAP_SIZE_Z);
}
}
}
}
else if(G.buts->mainb==CONTEXT_EDITING) {
ob= OBACT;
if(ob && ob->type==OB_CAMERA) {
else if(G.buts->mainb==CONTEXT_OBJECT) {
int tab= G.buts->tab[CONTEXT_OBJECT];
if(tab==TAB_OBJECT_EFFECTS) {
ob= OBACT;
if(ob && ob->type==OB_MESH) {
id= (ID *) (ob);
if(id) {
event= pupmenu("Insert Key %t|Surface Damping%x0|Random Damping%x1|Permeability%x2|Force Strength%x3|Force Falloff%x4");
if(event== -1) return;
if(event==0) {
insertkey(id, OB_PD_SDAMP);
}
if(event==1) {
insertkey(id, OB_PD_RDAMP);
}
if(event==2) {
insertkey(id, OB_PD_PERM);
}
if(event==3) {
insertkey(id, OB_PD_FSTR);
}
if(event==4) {
insertkey(id, OB_PD_FFALL);
}
}
}
}
else if(ob && ob->type==OB_CAMERA) {
id= G.buts->lockpoin;
if(id) {
event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1");

View File

@@ -87,10 +87,13 @@ void sdrawXORline(int x0, int y0, int x1, int y1)
void glutil_draw_front_xor_line(int x0, int y0, int x1, int y1)
{
glReadBuffer(GL_FRONT);
glDrawBuffer(GL_FRONT);
sdrawXORline(x0, y0, x1, y1);
glFlush();
glReadBuffer(GL_BACK);
glDrawBuffer(GL_BACK);
}
void sdrawXORline4(int nr, int x0, int y0, int x1, int y1)

View File

@@ -249,7 +249,7 @@ void buttons_active_id(ID **id, ID **idfrom)
else if(G.buts->tabo==TAB_SHADING_WORLD) G.buts->texfrom= 1;
else if(G.buts->tabo==TAB_SHADING_MAT) G.buts->texfrom= 0;
}
if(G.buts->texfrom==0) {
if(ob && ob->type<OB_LAMP && ob->type) {
ma= give_current_material(ob, ob->actcol);
@@ -510,7 +510,7 @@ void buts_buttons(void)
// uiDefIconBut(block, BUT, B_BUTSHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");
// xco+=XIC;
/* mainb menu */
/* mainb menu*/
/* (this could be done later with a dynamic tree and branches, also for python) */
//{
// char mainbname[8][12]= {" Scene", " Object", " Types", " Shading", " Editing", " Script", " Logic"};
@@ -542,7 +542,10 @@ void buts_buttons(void)
break;
case CONTEXT_OBJECT:
uiBlockBeginAlign(block);
uiDefIconButC(block, ROW, B_REDR, ICON_OBJECT, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_OBJECT, 0, 0, "Object ");
uiDefIconButC(block, ROW, B_REDR, ICON_EFFECTS, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_EFFECTS, 0, 0, "Effects");
break;
case CONTEXT_SHADING:
uiBlockBeginAlign(block);
@@ -557,7 +560,7 @@ void buts_buttons(void)
break;
case CONTEXT_SCRIPT:
break;
case CONTEXT_LOGIC: