forked from bartvdbraak/blender
Fix for bug #18924: OpenGL performance issue with particle modifiers,
actually two modifier datamask optimizations that were never done. * Don't use modifier data mask for disabled modifiers. * Check if UV data is needed for particle system instead of always requesting it.
This commit is contained in:
parent
afaa3768e6
commit
b8d0f62fd2
@ -202,7 +202,7 @@ typedef struct ModifierTypeInfo {
|
||||
*
|
||||
* This function is optional.
|
||||
*/
|
||||
CustomDataMask (*requiredDataMask)(struct ModifierData *md);
|
||||
CustomDataMask (*requiredDataMask)(struct Object *ob, struct ModifierData *md);
|
||||
|
||||
/* Free internal modifier data variables, this function should
|
||||
* not free the md variable itself.
|
||||
@ -270,6 +270,7 @@ int modifier_dependsOnTime(struct ModifierData *md);
|
||||
int modifier_supportsMapping(struct ModifierData *md);
|
||||
int modifier_couldBeCage(struct ModifierData *md);
|
||||
int modifier_isDeformer(struct ModifierData *md);
|
||||
int modifier_isEnabled(struct ModifierData *md, int required_mode);
|
||||
void modifier_setError(struct ModifierData *md, char *format, ...);
|
||||
|
||||
void modifiers_foreachObjectLink(struct Object *ob,
|
||||
@ -300,8 +301,10 @@ int modifiers_indexInObject(struct Object *ob, struct ModifierData *md
|
||||
* evaluation, assuming the data indicated by dataMask is required at the
|
||||
* end of the stack.
|
||||
*/
|
||||
struct LinkNode *modifiers_calcDataMasks(struct ModifierData *md,
|
||||
CustomDataMask dataMask);
|
||||
struct LinkNode *modifiers_calcDataMasks(struct Object *ob,
|
||||
struct ModifierData *md,
|
||||
CustomDataMask dataMask,
|
||||
int required_mode);
|
||||
struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob);
|
||||
|
||||
#endif
|
||||
|
@ -2134,18 +2134,18 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
if(useRenderParams) required_mode = eModifierMode_Render;
|
||||
else required_mode = eModifierMode_Realtime;
|
||||
|
||||
/* we always want to keep original indices */
|
||||
dataMask |= CD_MASK_ORIGINDEX;
|
||||
|
||||
datamasks = modifiers_calcDataMasks(md, dataMask);
|
||||
datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
|
||||
curr = datamasks;
|
||||
|
||||
if(deform_r) *deform_r = NULL;
|
||||
*final_r = NULL;
|
||||
|
||||
if(useRenderParams) required_mode = eModifierMode_Render;
|
||||
else required_mode = eModifierMode_Realtime;
|
||||
|
||||
if(useDeform) {
|
||||
if(useDeform > 0 && do_ob_key(ob)) /* shape key makes deform verts */
|
||||
deformedVerts = mesh_getVertexCos(me, &numVerts);
|
||||
@ -2156,8 +2156,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
for(;md; md = md->next, curr = curr->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if((md->mode & required_mode) != required_mode) continue;
|
||||
if(mti->isDisabled && mti->isDisabled(md)) continue;
|
||||
if(!modifier_isEnabled(md, required_mode)) continue;
|
||||
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
|
||||
|
||||
if(mti->type == eModifierTypeType_OnlyDeform) {
|
||||
@ -2221,19 +2220,18 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
for(;md; md = md->next, curr = curr->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if((md->mode & required_mode) != required_mode) continue;
|
||||
if(!modifier_isEnabled(md, required_mode)) continue;
|
||||
if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
|
||||
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
||||
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
||||
continue;
|
||||
}
|
||||
if(mti->isDisabled && mti->isDisabled(md)) continue;
|
||||
if(needMapping && !modifier_supportsMapping(md)) continue;
|
||||
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
|
||||
|
||||
/* add an orco layer if needed by this modifier */
|
||||
if(dm && mti->requiredDataMask) {
|
||||
mask = mti->requiredDataMask(md);
|
||||
mask = mti->requiredDataMask(ob, md);
|
||||
if(mask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, NULL, dm, orcodm);
|
||||
}
|
||||
@ -2405,14 +2403,11 @@ static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||
|
||||
if((md->mode & required_mode) != required_mode) return 0;
|
||||
if(!modifier_isEnabled(md, required_mode)) return 0;
|
||||
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
||||
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
||||
return 0;
|
||||
}
|
||||
if(mti->isDisabled && mti->isDisabled(md)) return 0;
|
||||
if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
|
||||
if(md->mode & eModifierMode_DisableTemporary) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2429,6 +2424,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
DerivedMesh *dm, *orcodm = NULL;
|
||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
LinkNode *datamasks, *curr;
|
||||
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
@ -2442,7 +2438,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
/* we always want to keep original indices */
|
||||
dataMask |= CD_MASK_ORIGINDEX;
|
||||
|
||||
datamasks = modifiers_calcDataMasks(md, dataMask);
|
||||
datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
|
||||
|
||||
curr = datamasks;
|
||||
for(i = 0; md; i++, md = md->next, curr = curr->next) {
|
||||
@ -2453,7 +2449,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
|
||||
/* add an orco layer if needed by this modifier */
|
||||
if(dm && mti->requiredDataMask) {
|
||||
mask = mti->requiredDataMask(md);
|
||||
mask = mti->requiredDataMask(ob, md);
|
||||
if(mask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, em, dm, orcodm);
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(tcmd->name, cmd->name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask curveModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CurveModifierData *cmd = (CurveModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -282,7 +282,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(tlmd->name, lmd->name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask latticeModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
LatticeModifierData *lmd = (LatticeModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -665,7 +665,7 @@ static void maskModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strcpy(tmmd->vgroup, mmd->vgroup);
|
||||
}
|
||||
|
||||
static CustomDataMask maskModifier_requiredDataMask(ModifierData *md)
|
||||
static CustomDataMask maskModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
return (1 << CD_MDEFORMVERT);
|
||||
}
|
||||
@ -3393,7 +3393,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask bevelModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
BevelModifierData *bmd = (BevelModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -3473,7 +3473,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask displaceModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -3816,7 +3816,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
tumd->aspecty = umd->aspecty;
|
||||
}
|
||||
|
||||
CustomDataMask uvprojectModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CustomDataMask dataMask = 0;
|
||||
|
||||
@ -4276,7 +4276,7 @@ int smoothModifier_isDisabled(ModifierData *md)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CustomDataMask smoothModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
SmoothModifierData *smd = (SmoothModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -4505,7 +4505,7 @@ int castModifier_isDisabled(ModifierData *md)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CustomDataMask castModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CastModifierData *cmd = (CastModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -5136,7 +5136,7 @@ static void waveModifier_updateDepgraph(
|
||||
}
|
||||
}
|
||||
|
||||
CustomDataMask waveModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
WaveModifierData *wmd = (WaveModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -5473,7 +5473,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask armatureModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CustomDataMask dataMask = 0;
|
||||
|
||||
@ -5587,7 +5587,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
strncpy(thmd->name, hmd->name, 32);
|
||||
}
|
||||
|
||||
CustomDataMask hookModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
HookModifierData *hmd = (HookModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -5846,7 +5846,7 @@ static void clothModifier_updateDepgraph(
|
||||
}
|
||||
}
|
||||
|
||||
CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CustomDataMask dataMask = 0;
|
||||
|
||||
@ -6230,7 +6230,7 @@ static DerivedMesh *booleanModifier_applyModifier(
|
||||
return derivedData;
|
||||
}
|
||||
|
||||
CustomDataMask booleanModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
|
||||
|
||||
@ -6278,12 +6278,27 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
|
||||
tpsmd->psys = psmd->psys;
|
||||
}
|
||||
|
||||
CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||
CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
|
||||
CustomDataMask dataMask = 0;
|
||||
Material *ma;
|
||||
MTex *mtex;
|
||||
int i;
|
||||
|
||||
ma= give_current_material(ob, psmd->psys->part->omat);
|
||||
if(ma) {
|
||||
for(i=0; i<MAX_MTEX; i++) {
|
||||
mtex=ma->mtex[i];
|
||||
if(mtex && (ma->septex & (1<<i))==0)
|
||||
if(mtex->pmapto && (mtex->texco & TEXCO_UV))
|
||||
dataMask |= (1 << CD_MTFACE);
|
||||
}
|
||||
}
|
||||
|
||||
if(psmd->psys->part->tanfac!=0.0)
|
||||
dataMask |= (1 << CD_MTFACE);
|
||||
|
||||
/* ask for vertexgroups if we need them */
|
||||
for(i=0; i<PSYS_TOT_VG; i++){
|
||||
if(psmd->psys->vgroup[i]){
|
||||
@ -6638,7 +6653,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -7552,7 +7567,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
tmmd->object = mmd->object;
|
||||
}
|
||||
|
||||
CustomDataMask meshdeformModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -7876,7 +7891,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
tsmd->subsurfLevels = smd->subsurfLevels;
|
||||
}
|
||||
|
||||
CustomDataMask shrinkwrapModifier_requiredDataMask(ModifierData *md)
|
||||
CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -7910,7 +7925,7 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O
|
||||
static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = NULL;
|
||||
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
|
||||
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
|
||||
|
||||
/* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
|
||||
if(dataMask)
|
||||
@ -7936,7 +7951,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived
|
||||
static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = NULL;
|
||||
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
|
||||
CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
|
||||
|
||||
if(dataMask)
|
||||
{
|
||||
@ -7995,7 +8010,7 @@ static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target
|
||||
memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
|
||||
}
|
||||
|
||||
static CustomDataMask simpledeformModifier_requiredDataMask(ModifierData *md)
|
||||
static CustomDataMask simpledeformModifier_requiredDataMask(Object *ob, ModifierData *md)
|
||||
{
|
||||
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
@ -8024,7 +8039,7 @@ static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *for
|
||||
static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = NULL;
|
||||
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md);
|
||||
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
|
||||
|
||||
/* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
|
||||
if(dataMask)
|
||||
@ -8051,7 +8066,7 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv
|
||||
static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
DerivedMesh *dm = NULL;
|
||||
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md);
|
||||
CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
|
||||
|
||||
/* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
|
||||
if(dataMask)
|
||||
@ -8658,7 +8673,20 @@ int modifiers_isParticleEnabled(Object *ob)
|
||||
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
||||
}
|
||||
|
||||
LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
|
||||
int modifier_isEnabled(ModifierData *md, int required_mode)
|
||||
{
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if((md->mode & required_mode) != required_mode) return 0;
|
||||
if(mti->isDisabled && mti->isDisabled(md)) return 0;
|
||||
if(md->mode & eModifierMode_DisableTemporary) return 0;
|
||||
if(required_mode & eModifierMode_Editmode)
|
||||
if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
LinkNode *modifiers_calcDataMasks(Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode)
|
||||
{
|
||||
LinkNode *dataMasks = NULL;
|
||||
LinkNode *curr, *prev;
|
||||
@ -8668,7 +8696,9 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
CustomDataMask mask = 0;
|
||||
|
||||
if(mti->requiredDataMask) mask = mti->requiredDataMask(md);
|
||||
if(modifier_isEnabled(md, required_mode))
|
||||
if(mti->requiredDataMask)
|
||||
mask = mti->requiredDataMask(ob, md);
|
||||
|
||||
BLI_linklist_prepend(&dataMasks, (void *)mask);
|
||||
}
|
||||
|
@ -3182,7 +3182,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
|
||||
if(ma) for(m=0; m<MAX_MTEX; m++){
|
||||
mtex=ma->mtex[m];
|
||||
if(mtex && (ma->septex & (1<<m))==0){
|
||||
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
|
||||
float def=mtex->def_var;
|
||||
float var=mtex->varfac;
|
||||
short blend=mtex->blendtype;
|
||||
@ -3231,7 +3231,7 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
|
||||
|
||||
if(ma) for(m=0; m<MAX_MTEX; m++){
|
||||
mtex=ma->mtex[m];
|
||||
if(mtex && (ma->septex & (1<<m))==0){
|
||||
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
|
||||
float var=mtex->varfac;
|
||||
float def=mtex->def_var;
|
||||
short blend=mtex->blendtype;
|
||||
|
@ -1762,7 +1762,10 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
|
||||
where_is_object_time(ob,pa->time);
|
||||
|
||||
/* get birth location from object */
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
|
||||
if(part->tanfac!=0.0)
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
|
||||
else
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||
|
||||
/* save local coordinates for later */
|
||||
VECCOPY(tloc,loc);
|
||||
|
Loading…
Reference in New Issue
Block a user