Revision: 30071 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30071 Author: lukastoenne Date: 2010-07-07 10:10:43 +0200 (Wed, 07 Jul 2010)
Log Message: ----------- Basic particle buffers ported back. This needs to be extended to include particle properties. Modified Paths: -------------- branches/particles-2010/source/blender/blenkernel/BKE_particleset.h branches/particles-2010/source/blender/blenkernel/intern/object.c branches/particles-2010/source/blender/blenkernel/intern/particleset.c branches/particles-2010/source/blender/editors/particleset/editparticleset.c branches/particles-2010/source/blender/makesdna/DNA_particleset_types.h branches/particles-2010/source/blender/makesdna/intern/makesdna.c Modified: branches/particles-2010/source/blender/blenkernel/BKE_particleset.h =================================================================== --- branches/particles-2010/source/blender/blenkernel/BKE_particleset.h 2010-07-07 07:24:09 UTC (rev 30070) +++ branches/particles-2010/source/blender/blenkernel/BKE_particleset.h 2010-07-07 08:10:43 UTC (rev 30071) @@ -32,8 +32,41 @@ struct ParticleSet; +/* attribute management */ +int pset_get_particle_size(struct ParticleSet *pset); + +/* buffer management */ +void pset_create_particles(struct ParticleSet *pset, float cfra, int emit); +void pset_kill_particle(struct ParticleSet *pset, int index); +void pset_kill_all_particles(struct ParticleSet *pset); +void pset_free_dead_pages(struct ParticleSet *pset); +void pset_free_particles(struct ParticleSet *pset); +void pset_reset(struct ParticleSet *pset); + +/* particle access */ +struct Particle* pset_get_particle(struct ParticleSet *pset, int index); + +struct ParticleIterator; +typedef int (*ParticleIteratorSkipFunc)(struct ParticleIterator*); +typedef struct ParticleIterator +{ + ParticleSet *pset; + Particle *pa; + int index; + ParticlePage *page; + + ParticleIteratorSkipFunc skip; +} ParticleIterator; + +void pit_init_skip(struct ParticleIterator *it, struct ParticleSet *pset, ParticleIteratorSkipFunc skip); +void pit_init(struct ParticleIterator *it, struct ParticleSet *pset); +void pit_next(struct ParticleIterator *it); +void pit_goto(struct ParticleIterator *it, int index); + void make_local_particleset(struct ParticleSet *pset); +struct ParticleSet *add_particleset(char *name); struct ParticleSet* copy_particleset(struct ParticleSet *pset); +void unlink_particleset(struct ParticleSet *pset); void free_particleset(struct ParticleSet *pset); #endif Modified: branches/particles-2010/source/blender/blenkernel/intern/object.c =================================================================== --- branches/particles-2010/source/blender/blenkernel/intern/object.c 2010-07-07 07:24:09 UTC (rev 30070) +++ branches/particles-2010/source/blender/blenkernel/intern/object.c 2010-07-07 08:10:43 UTC (rev 30071) @@ -87,6 +87,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_particleset.h" #include "BKE_pointcache.h" #include "BKE_property.h" #include "BKE_sca.h" @@ -965,6 +966,7 @@ case OB_SURF: return add_curve("Surf", OB_SURF); case OB_FONT: return add_curve("Text", OB_FONT); case OB_MBALL: return add_mball("Meta"); + case OB_PSET: return add_particleset("Particles"); case OB_CAMERA: return add_camera("Camera"); case OB_LAMP: return add_lamp("Lamp"); case OB_LATTICE: return add_lattice("Lattice"); @@ -985,6 +987,7 @@ case OB_SURF: return "Surf"; case OB_FONT: return "Text"; case OB_MBALL: return "Mball"; + case OB_PSET: return "Particles"; case OB_CAMERA: return "Camera"; case OB_LAMP: return "Lamp"; case OB_LATTICE: return "Lattice"; Modified: branches/particles-2010/source/blender/blenkernel/intern/particleset.c =================================================================== --- branches/particles-2010/source/blender/blenkernel/intern/particleset.c 2010-07-07 07:24:09 UTC (rev 30070) +++ branches/particles-2010/source/blender/blenkernel/intern/particleset.c 2010-07-07 08:10:43 UTC (rev 30071) @@ -25,22 +25,488 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "DNA_object_types.h" #include "DNA_particleset_types.h" #include "MEM_guardedalloc.h" +#include "BLI_math.h" + +#include "BKE_animsys.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_particleset.h" +#include "BKE_utildefines.h" +/* attribute management */ +/* TODO */ + +int pset_get_particle_size(ParticleSet *pset) +{ + return sizeof(Particle); +} + +/* buffer management */ +static void init_particle(ParticleSet *pset, Particle *pa) +{ + pa->birthtime = 0.0f; + zero_v3(pa->loc); + zero_v3(pa->vel); +} + +static void init_page(ParticleSet *pset, ParticlePage *page, int page_size) +{ + Particle *pa; + int psize= pset_get_particle_size(pset); + int p; + + page->particles = MEM_callocN(page_size * psize, "ParticlePage"); + + /* initialise new particles */ + for (p=0, pa=(Particle*)page->particles; p < page_size; ++p, pa = (Particle*)((char*)pa + psize)) { + init_particle(pset, pa); + } + + page->fill = 0; + page->alive = 0; +} + +static void free_page(ParticleSet *pset, ParticlePage *page) +{ + if (page->particles) { + MEM_freeN(page->particles); + page->particles = NULL; + } +} + +#if 0 +static void copy_particle_data(ParticlePage *dest, ParticlePage *src, int from, int num, int psize) +{ + memcpy(dest->particles + (from - dest->index), src->particles + (from - src->index), num * psize); +} + +static void set_page_size(ParticleSet *pset, int new_page_size) +{ + if (pset->page_size != new_page_size) { + int new_totpages = (pset->totpart+new_page_size-1)/new_page_size; /* rounding up */ + ParticlePage *new_pages = NULL; + if (new_totpages > 0) { + int cp, p, alive; + int npg; + ParticlePage *page, *npage; + + new_pages = MEM_callocN(new_totpages * sizeof(ParticlePage), "ParticlePage array"); + + if (pset->pages) { + cp = 0; + page = pset->pages; + npage = new_pages; + npage->index = 0; + npage->fill = npage->alive = 0; + npage->particles = NULL; + while (cp < pset->totpart) { + int copy_all = pset->totpart - cp; + int copy_page = page->index + page->fill - cp; + int copy_npage = npage->index + new_page_size - cp; + int copy = MIN2(copy_all, MIN2(copy_page, copy_npage)); + + if (page->particles) { + alive = 0; + for (p=0; p < copy; ++p) + if (page->particles[cp-page->index + p].alive == PARS_ALIVE) + ++alive; + if (!npage->particles && alive > 0) { + init_page(pset, npage, new_page_size); + /* start page at cp */ + npage->fill = cp - npage->index; + /* mark previous particles as dead */ + for (p=0; p < npage->fill; ++p) + npage->particles[p].alive = PARS_DEAD; + } + if (npage->particles) { + copy_particle_data(npage, page, cp, copy); + npage->alive += alive; + } + } else if (npage->particles) { + /* mark particles as dead */ + for (p=0; p < copy; ++p) + npage->particles[cp-npage->index + p].alive = PARS_DEAD; + } + npage->fill += copy; + cp += copy; + + if (copy == copy_page) { + free_page(pset, page); + ++page; + } + + if (copy == copy_npage) { + ++npage; + npg= npage - new_pages; + if (npg < new_totpages) { + + npage->index = npg * new_page_size; + npage->fill = npage->alive = 0; + npage->particles = NULL; + } + } + } + } + } + if (pset->pages) + MEM_freeN(pset->pages); + pset->pages = new_pages; + pset->totpages = new_totpages; + pset->page_size = new_page_size; + } + + #if 0 /* Debugging - phonybone */ + printf("page size set to %d: totpart=%d, totalive=%d, pages=%d\n", pset->page_size, pset->totpart, pset->totalive, pset->totpages); + if (pset->pages) { + int pg, p; + for (pg=0; pg < pset->totpages; ++pg) { + if (pset->pages[pg].particles) { + printf("%d [%d/%d]: \t", pset->pages[pg].index, pset->pages[pg].alive, pset->pages[pg].fill); + for (p=0; p < pset->page_size; ++p) { + if (pset->pages[pg].particles[p].alive == PARS_UNBORN) + printf("U "); + else if (pset->pages[pg].particles[p].alive == PARS_ALIVE) + printf("A "); + else if (pset->pages[pg].particles[p].alive == PARS_DEAD) + printf("D "); + } + printf("\n"); + } + else { + printf("%d [%d/%d]: \t", pset->pages[pg].index, pset->pages[pg].alive, pset->pages[pg].fill); + for (p=0; p < pset->page_size; ++p) { + printf("- "); + } + printf("\n"); + } + } + } + printf("--------------------------------------------------------------------------------------------\n"); + #endif +} +#endif + +static void activate_particle(ParticleSet *pset, float cfra, Particle *pa, int p) +{ + pa->birthtime = cfra; +} + +void pset_create_particles(ParticleSet *pset, float cfra, int emit) +{ + int p, k; /* counters for pages, particles */ + int num_new_pages; /* new pages to allocate */ + int new_pages_emit; /* particles in new pages */ + int index; /* start index */ + ParticlePage *page; + int psize= pset_get_particle_size(pset); + Particle *pa; + + if (emit <= 0) return; + + /* calculate number of new pages required */ + new_pages_emit = emit; + if (pset->totpages > 0) + new_pages_emit -= pset->page_size - pset->pages[pset->totpages-1].fill; + num_new_pages= (new_pages_emit + pset->page_size-1) / pset->page_size; /* rounding up! */ + + /* create a new page array if necessary, else fill up the last page */ + if (num_new_pages > 0) { + /* allocate bigger page array and copy old pages */ + page = MEM_callocN(sizeof(ParticlePage) * (pset->totpages + num_new_pages), "ParticlePage array"); + if (pset->pages) { + memcpy(page, pset->pages, sizeof(ParticlePage) * pset->totpages); + MEM_freeN(pset->pages); + } + pset->pages = page; + /* init new pages */ + index = pset->totpages * pset->page_size; + for (p=0, page=pset->pages + pset->totpages; p < num_new_pages; ++p, ++page) { + page->index = index; + index += pset->page_size; + init_page(pset, page, pset->page_size); + } + + /* activate emitted particles */ + if (pset->totpages > 0) { + page = pset->pages + (pset->totpages-1); + for (k = 0, pa=(Particle*)((char*)page->particles + page->fill * psize); k < pset->page_size - page->fill; ++k, pa = (Particle*)((char*)pa + psize)) { + activate_particle(pset, cfra, pa, (pset->totpages-1)*pset->page_size + k); + ++page->alive; + ++pset->totalive; + } + page->fill = pset->page_size; /* last page completely filled */ + } + for (p=0, page=pset->pages + pset->totpages; p < num_new_pages; ++p, ++page) { + page->fill = MIN2(new_pages_emit - p * pset->page_size, pset->page_size); + for (k = 0, pa = (Particle*)page->particles; k < page->fill; ++k, pa = (Particle*)((char*)pa + psize)) { + activate_particle(pset, cfra, pa, (p + pset->totpages)*pset->page_size + k); + ++page->alive; + ++pset->totalive; + } + } + + pset->totpages += num_new_pages; + } + else { + page = pset->pages + (pset->totpages-1); + /* activate emitted particles */ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs