add angular velocity

This commit is contained in:
cxgeorge 2002-08-30 23:59:36 +00:00
parent e789201a5e
commit 12a8319f8e
8 changed files with 187 additions and 55 deletions

View File

@ -52,13 +52,13 @@ class Particles(ParticleSystem.ParticleSystem):
self.setRenderParent(self.node)
self.node.addPhysical(self)
self.factory = None
self.factory = None
self.factoryType = "undefined"
self.setFactory("PointParticleFactory")
self.renderer = None
self.renderer = None
self.rendererType = "undefined"
self.setRenderer("PointParticleRenderer")
self.emitter = None
self.emitter = None
self.emitterType = "undefined"
self.setEmitter("SphereVolumeEmitter")
@ -106,7 +106,7 @@ class Particles(ParticleSystem.ParticleSystem):
self.factory = None
self.factoryType = type
if (type == "PointParticleFactory"):
self.factory = PointParticleFactory.PointParticleFactory()
self.factory = PointParticleFactory.PointParticleFactory()
elif (type == "ZSpinParticleFactory"):
self.factory = ZSpinParticleFactory.ZSpinParticleFactory()
elif (type == "OrientedParticleFactory"):
@ -263,31 +263,40 @@ class Particles(ParticleSystem.ParticleSystem):
file.write('# Z Spin factory parameters\n')
file.write(targ + '.factory.setInitialAngle(%.4f)\n' % \
self.factory.getInitialAngle())
file.write(targ + '.factory.setFinalAngle(%.4f)\n' % \
self.factory.getFinalAngle())
file.write(targ + '.factory.setInitialAngleSpread(%.4f)\n' % \
self.factory.getInitialAngleSpread())
file.write(targ + '.factory.setFinalAngleSpread(%.4f)\n' % \
file.write(targ + '.factory.enableAngularVelocity(%d)\n' % \
self.factory.getAngularVelocityEnabled())
if(self.factory.getAngularVelocityEnabled()):
file.write(targ + '.factory.setAngularVelocity(%.4f)\n' % \
self.factory.getAngularVelocity())
file.write(targ + '.factory.setAngularVelocitySpread(%.4f)\n' % \
self.factory.getAngularVelocitySpread())
else:
file.write(targ + '.factory.setFinalAngle(%.4f)\n' % \
self.factory.getFinalAngle())
file.write(targ + '.factory.setFinalAngleSpread(%.4f)\n' % \
self.factory.getFinalAngleSpread())
elif (self.factoryType == "OrientedParticleFactory"):
file.write('# Oriented factory parameters\n')
file.write(targ + '.factory.setInitialOrientation(%.4f)\n' % \
self.factory.getInitialOrientation())
self.factory.getInitialOrientation())
file.write(targ + '.factory.setFinalOrientation(%.4f)\n' % \
self.factory.getFinalOrientation())
file.write('# Renderer parameters\n')
alphaMode = self.renderer.getAlphaMode()
aMode = "PRALPHANONE"
aMode = "PRALPHANONE"
if (alphaMode == BaseParticleRenderer.BaseParticleRenderer.PRALPHANONE):
aMode = "PRALPHANONE"
elif (alphaMode ==
elif (alphaMode ==
BaseParticleRenderer.BaseParticleRenderer.PRALPHAOUT):
aMode = "PRALPHAOUT"
elif (alphaMode ==
elif (alphaMode ==
BaseParticleRenderer.BaseParticleRenderer.PRALPHAIN):
aMode = "PRALPHAIN"
elif (alphaMode ==
elif (alphaMode ==
BaseParticleRenderer.BaseParticleRenderer.PRALPHAUSER):
aMode = "PRALPHAUSER"
file.write(targ + '.renderer.setAlphaMode(BaseParticleRenderer.' + aMode + ')\n')
@ -298,9 +307,9 @@ class Particles(ParticleSystem.ParticleSystem):
file.write(targ + '.renderer.setPointSize(%.2f)\n' % \
self.renderer.getPointSize())
sColor = self.renderer.getStartColor()
file.write((targ + '.renderer.setStartColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
file.write((targ + '.renderer.setStartColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
sColor = self.renderer.getEndColor()
file.write((targ + '.renderer.setEndColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
file.write((targ + '.renderer.setEndColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
blendType = self.renderer.getBlendType()
bType = "PPONECOLOR"
if (blendType == PointParticleRenderer.PointParticleRenderer.PPONECOLOR):

View File

@ -214,7 +214,7 @@ class ParticlePanel(AppShell):
0.0, None)
)
self.createFloaters(systemPage, systemFloaterDefs)
# Checkboxes
self.createCheckbutton(
systemPage, 'System', 'Render Space Velocities',
@ -225,7 +225,7 @@ class ParticlePanel(AppShell):
systemPage, 'System', 'System Grows Older',
'On: system has a lifespan',
self.toggleSystemGrowsOlder, 0)
# Vector widgets
pos = self.createVector3Entry(systemPage, 'System', 'Pos',
'Particle system position',
@ -269,7 +269,8 @@ class ParticlePanel(AppShell):
('Factory', 'Terminal Vel. Spread',
'Variation in terminal velocity',
self.setFactoryTerminalVelocitySpread,
0.0, None))
0.0, None),
)
self.createFloaters(factoryPage, factoryWidgets)
self.factoryNotebook = Pmw.NoteBook(factoryPage, tabpos = None)
@ -277,6 +278,23 @@ class ParticlePanel(AppShell):
factoryPointPage = self.factoryNotebook.add('PointParticleFactory')
# Z spin page #
zSpinPage = self.factoryNotebook.add('ZSpinParticleFactory')
self.createCheckbutton(
zSpinPage, 'Z Spin Factory', 'Enable Angular Velocity',
("On: angular velocity is used; " +
"Off: final angle is used"),
self.toggleAngularVelocity, 0, side = TOP),
self.createFloater(
zSpinPage, 'Z Spin Factory', 'Angular Velocity',
'How fast sprites rotate',
command = self.setFactoryZSpinAngularVelocity)
self.createFloater(
zSpinPage, 'Z Spin Factory', 'Angular Velocity Spread',
'Variation in how fast sprites rotate',
command = self.setFactoryZSpinAngularVelocitySpread)
self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Initial Angle',
'Starting angle in degrees',
fRollover = 1,
@ -338,33 +356,33 @@ class ParticlePanel(AppShell):
self.emissionType, BaseParticleEmitter.ETCUSTOM,
self.setEmissionType)
emissionFrame.pack(fill = 'x', expand = 0)
self.createFloater(
emitterPage, 'Emitter', 'Velocity Multiplier',
'launch velocity multiplier (all emission modes)',
command = self.setEmitterAmplitude,
min = None)
self.createFloater(
emitterPage, 'Emitter', 'Velocity Multiplier Spread',
'spread for launch velocity multiplier (all emission modes)',
command = self.setEmitterAmplitudeSpread)
self.createVector3Entry(
emitterPage, 'Emitter', 'Offset Velocity',
'Velocity vector applied to all particles',
command = self.setEmitterOffsetForce)
self.createVector3Entry(
emitterPage, 'Emitter', 'Explicit Velocity',
'all particles launch with this velocity in Explicit mode',
command = self.setEmitterExplicitLaunchVector)
self.createVector3Entry(
emitterPage, 'Emitter', 'Radiate Origin',
'particles launch away from this point in Radiate mode',
command = self.setEmitterRadiateOrigin)
self.emitterNotebook = Pmw.NoteBook(emitterPage, tabpos = None)
# Box page #
boxPage = self.emitterNotebook.add('BoxEmitter')
@ -399,7 +417,7 @@ class ParticlePanel(AppShell):
'On: magnitude/angle interpolation from center',
self.toggleEmitterDiscCubicLerping, 0)
customPage.pack(fill = BOTH, expand = 1)
# Line page #
linePage = self.emitterNotebook.add('LineEmitter')
self.createVector3Entry(linePage, 'Line Emitter', 'Min',
@ -435,7 +453,7 @@ class ParticlePanel(AppShell):
'Particle launch angle',
command = self.setEmitterRingLaunchAngle)
self.ringCustomFrame.pack(fill = BOTH, expand = 1)
# Sphere volume #
sphereVolumePage = self.emitterNotebook.add('SphereVolumeEmitter')
self.createFloater(sphereVolumePage, 'Sphere Volume Emitter', 'Radius',
@ -449,7 +467,7 @@ class ParticlePanel(AppShell):
'Radius of sphere',
command = self.setEmitterSphereSurfaceRadius,
min = 0.01)
# Tangent ring #
# Tangent ring #
tangentRingPage = self.emitterNotebook.add('TangentRingEmitter')
self.createFloater(tangentRingPage, 'Tangent Ring Emitter', 'Radius',
'Radius of ring',
@ -471,12 +489,12 @@ class ParticlePanel(AppShell):
"alpha setting over particles' lifetime",
('NO_ALPHA','ALPHA_OUT','ALPHA_IN','ALPHA_USER'),
self.setRendererAlphaMode)
self.createSlider(
rendererPage, 'Renderer', 'User Alpha',
'alpha value for ALPHA_USER alpha mode',
command = self.setRendererUserAlpha)
self.rendererNotebook = Pmw.NoteBook(rendererPage, tabpos = None)
# Line page #
linePage = self.rendererNotebook.add('LineParticleRenderer')
@ -666,7 +684,7 @@ class ParticlePanel(AppShell):
# This also has: setCoef, setLength, setRadius,
forceMenu.add_command(label = 'Add Linear Cylinder Vortex Force',
command = self.addLinearCylinderVortexForce)
# DERIVED FROM LINEAR DISTANCE FORCE
# Parameters: setFalloffType, setForceCenter, setRadius
forceMenu.add_command(label = 'Add Linear Sink Force',
@ -688,14 +706,14 @@ class ParticlePanel(AppShell):
# Notebook to hold force widgets as the are added
self.forceGroupNotebook = Pmw.NoteBook(self.forceFrame, tabpos = None)
self.forceGroupNotebook.pack(fill = X)
self.factoryNotebook.setnaturalsize()
self.emitterNotebook.setnaturalsize()
self.rendererNotebook.setnaturalsize()
self.forceGroupNotebook.setnaturalsize()
self.mainNotebook.setnaturalsize()
# Make sure input variables processed
# Make sure input variables processed
self.initialiseoptions(ParticlePanel)
### WIDGET UTILITY FUNCTIONS ###
@ -712,7 +730,7 @@ class ParticlePanel(AppShell):
self.widgetDict[category + '-' + text] = widget
self.variableDict[category + '-' + text] = bool
return widget
def createRadiobutton(self, parent, side, category, text,
balloonHelp, variable, value,
command):
@ -724,7 +742,7 @@ class ParticlePanel(AppShell):
self.bind(widget, balloonHelp)
self.widgetDict[category + '-' + text] = widget
return widget
def createFloaters(self, parent, widgetDefinitions):
widgets = []
for category, label, balloonHelp, command, min, resolution in widgetDefinitions:
@ -864,7 +882,7 @@ class ParticlePanel(AppShell):
self.forceGroupLabel['text'] = self.forceGroup.getName()
else:
self.forceGroupLabel['text'] = 'Force Group'
def updateMenus(self):
self.updateEffectsMenus()
self.updateParticlesMenus()
@ -878,7 +896,7 @@ class ParticlePanel(AppShell):
# Add in a checkbutton for each effect (to toggle on/off)
keys = self.effectsDict.keys()
keys.sort()
for name in keys:
for name in keys:
effect = self.effectsDict[name]
self.effectsLabelMenu.add_command(
label = effect.getName(),
@ -966,7 +984,7 @@ class ParticlePanel(AppShell):
effect.enable()
else:
effect.disable()
def selectParticlesNamed(self, name):
particles = self.particleEffect.getParticlesNamed(name)
if particles != None:
@ -997,13 +1015,13 @@ class ParticlePanel(AppShell):
force.setActive(1)
else:
force.setActive(0)
def getWidget(self, category, text):
return self.widgetDict[category + '-' + text]
def getVariable(self, category, text):
return self.variableDict[category + '-' + text]
def loadParticleEffectFromFile(self):
# Find path to particle directory
pPath = getParticlePath()
@ -1083,7 +1101,7 @@ class ParticlePanel(AppShell):
self.particleEffect.enable()
else:
self.particleEffect.disable()
## SYSTEM PAGE ##
def updateSystemWidgets(self):
poolSize = self.particles.getPoolSize()
@ -1133,7 +1151,7 @@ class ParticlePanel(AppShell):
def selectFactoryPage(self):
pass
def updateFactoryWidgets(self):
factory = self.particles.factory
lifespan = factory.getLifespanBase()
@ -1149,7 +1167,7 @@ class ParticlePanel(AppShell):
terminalVelocitySpread = factory.getTerminalVelocitySpread()
self.getWidget('Factory', 'Terminal Vel. Spread').set(
terminalVelocitySpread, 0)
def setFactoryLifeSpan(self, value):
self.particles.factory.setLifespanBase(value)
def setFactoryLifeSpanSpread(self, value):
@ -1172,6 +1190,10 @@ class ParticlePanel(AppShell):
self.particles.factory.setFinalAngle(angle)
def setFactoryZSpinFinalAngleSpread(self, spread):
self.particles.factory.setFinalAngleSpread(spread)
def setFactoryZSpinAngularVelocity(self, vel):
self.particles.factory.setAngularVelocity(vel)
def setFactoryZSpinAngularVelocitySpread(self, spread):
self.particles.factory.setAngularVelocitySpread(spread)
## EMITTER PAGE ##
def selectEmitterType(self, type):
@ -1183,7 +1205,7 @@ class ParticlePanel(AppShell):
type = self.particles.emitter.__class__.__name__
self.emitterNotebook.selectpage(type)
self.getVariable('Emitter', 'Emitter Type').set(type)
def updateEmitterWidgets(self):
emitter = self.particles.emitter
self.setEmissionType(self.particles.emitter.getEmissionType())
@ -1371,7 +1393,7 @@ class ParticlePanel(AppShell):
self.rendererNotebook.selectpage(type)
self.particles.setRenderer(type)
self.updateRendererWidgets()
def updateRendererWidgets(self):
renderer = self.particles.renderer
alphaMode = renderer.getAlphaMode()
@ -1571,8 +1593,8 @@ class ParticlePanel(AppShell):
self.rendererSpriteFileEntry['state'] = 'disabled'
self.rendererSpriteNodeEntry['state'] = 'disabled'
self.rendererSpriteTextureEntry['background'] = 'SystemWindow'
self.rendererSpriteFileEntry['background'] = '#C0C0C0'
self.rendererSpriteNodeEntry['background'] = '#C0C0C0'
self.rendererSpriteFileEntry['background'] = '#C0C0C0'
self.rendererSpriteNodeEntry['background'] = '#C0C0C0'
else:
self.rendererSpriteTextureEntry['state'] = 'disabled'
self.rendererSpriteFileEntry['state'] = 'normal'
@ -1599,6 +1621,11 @@ class ParticlePanel(AppShell):
def toggleRendererSpriteAnimAngle(self):
self.particles.renderer.setAnimAngleFlag(
self.getVariable('Sprite Renderer', 'Anim Angle').get())
def toggleAngularVelocity(self):
self.particles.factory.enableAngularVelocity(
self.getVariable('Z Spin Factory', 'Enable Angular Velocity').get())
def setRendererSpriteInitialXScale(self, xScale):
self.particles.renderer.setInitialXScale(xScale)
def setRendererSpriteFinalXScale(self, xScale):
@ -1623,7 +1650,7 @@ class ParticlePanel(AppShell):
def toggleRendererSpriteAlphaDisable(self):
self.particles.renderer.setAlphaDisable(
self.getVariable('Sprite Renderer', 'Alpha Disable').get())
## FORCEGROUP COMMANDS ##
def updateForceWidgets(self):
# Select appropriate notebook page

View File

@ -51,3 +51,25 @@ INLINE float ZSpinParticle::
get_final_angle(void) const {
return _final_angle;
}
INLINE float ZSpinParticle::
get_angular_velocity(void) const {
return _angular_velocity;
}
INLINE void ZSpinParticle::
set_angular_velocity(float v) {
_angular_velocity = v;
}
INLINE void ZSpinParticle::
enable_angular_velocity(bool bEnabled) {
_bUseAngularVelocity = bEnabled;
}
INLINE bool ZSpinParticle::
get_angular_velocity_enabled(void) const {
return _bUseAngularVelocity;
}

View File

@ -29,6 +29,8 @@ ZSpinParticle(void) :
_initial_angle = 0.0f;
_final_angle = 0.0f;
_cur_angle = 0.0f;
_angular_velocity = 0.0f;
_bUseAngularVelocity = false;
}
////////////////////////////////////////////////////////////////////
@ -42,6 +44,8 @@ ZSpinParticle(const ZSpinParticle &copy) :
_initial_angle = copy._initial_angle;
_final_angle = copy._final_angle;
_cur_angle = copy._cur_angle;
_angular_velocity = copy._angular_velocity;
_bUseAngularVelocity = copy._bUseAngularVelocity;
}
////////////////////////////////////////////////////////////////////
@ -79,17 +83,23 @@ init(void) {
////////////////////////////////////////////////////////////////////
void ZSpinParticle::
update(void) {
float t = get_parameterized_age();
// if using final_angle, want age to range from [0,1] over lifespan, so use parameterized_age
// for angular velocity, should be allowed to range freely upward, use regular age
// interpolate the current orientation
_cur_angle = _initial_angle + (t * (_final_angle - _initial_angle));
if(_bUseAngularVelocity) {
// interpolate the current orientation
_cur_angle = _initial_angle + (get_age() * _angular_velocity);
} else {
_cur_angle = _initial_angle + (get_parameterized_age() * (_final_angle - _initial_angle));
}
// normalize the result to [0..360)
_cur_angle = fmod(_cur_angle, 360.0f);
// if _cur_angle was negative, it is still negative after fmod,
// but greater than -360.
// wrap it around by adding 360
// is this really necessary? should be in range of sin/cos
if(_cur_angle < 0.0f)
_cur_angle += 360.0f;
}

View File

@ -34,6 +34,8 @@ private:
float _initial_angle;
float _final_angle;
float _cur_angle;
float _angular_velocity;
bool _bUseAngularVelocity;
public:
ZSpinParticle(void);
@ -53,6 +55,14 @@ public:
INLINE void set_final_angle(float t);
INLINE float get_final_angle(void) const;
// 'set_final_angle' and 'angular_velocity' are mutually exclusive apis
// if angular-velocity is specified, final_angle is ignored
INLINE void set_angular_velocity(float v);
INLINE float get_angular_velocity(void) const;
INLINE void enable_angular_velocity(bool bEnabled);
INLINE bool get_angular_velocity_enabled(void) const;
};
#include "zSpinParticle.I"

View File

@ -88,3 +88,39 @@ INLINE float ZSpinParticleFactory::
get_final_angle_spread(void) const {
return _final_angle_spread;
}
////////////////////////////////////////////////////////////////////
// Function : get_angular_velocity
// Access : public
////////////////////////////////////////////////////////////////////
INLINE float ZSpinParticleFactory::
get_angular_velocity(void) const {
return _angular_velocity;
}
INLINE void ZSpinParticleFactory::
set_angular_velocity(float v) {
_angular_velocity = v;
}
INLINE float ZSpinParticleFactory::
get_angular_velocity_spread(void) const {
return _angular_velocity_spread;
}
INLINE void ZSpinParticleFactory::
set_angular_velocity_spread(float spread) {
_angular_velocity_spread = spread;
}
INLINE void ZSpinParticleFactory::
enable_angular_velocity(bool bEnabled) {
_bUseAngularVelocity = bEnabled;
}
INLINE bool ZSpinParticleFactory::
get_angular_velocity_enabled(void) const {
return _bUseAngularVelocity;
}

View File

@ -31,6 +31,9 @@ ZSpinParticleFactory(void) :
_final_angle = 0.0f;
_initial_angle_spread = 0.0f;
_final_angle_spread = 0.0f;
_angular_velocity = 0.0f;
_angular_velocity_spread = 0.0f;
_bUseAngularVelocity = false;
}
////////////////////////////////////////////////////////////////////
@ -45,6 +48,9 @@ ZSpinParticleFactory(const ZSpinParticleFactory &copy) :
_final_angle = copy._final_angle;
_initial_angle_spread = copy._initial_angle_spread;
_final_angle_spread = copy._final_angle_spread;
_angular_velocity = copy._angular_velocity;
_angular_velocity_spread = copy._angular_velocity_spread;
_bUseAngularVelocity = copy._bUseAngularVelocity;
}
////////////////////////////////////////////////////////////////////
@ -77,4 +83,6 @@ populate_child_particle(BaseParticle *bp) const {
zsp->set_initial_angle(_initial_angle + SPREAD(_initial_angle_spread));
zsp->set_final_angle(_final_angle + SPREAD(_final_angle_spread));
zsp->set_angular_velocity(_angular_velocity + SPREAD(_angular_velocity_spread));
zsp->enable_angular_velocity(_bUseAngularVelocity);
}

View File

@ -31,10 +31,11 @@ private:
virtual void populate_child_particle(BaseParticle *bp) const;
virtual BaseParticle *alloc_particle(void) const;
float _initial_angle;
float _final_angle;
float _initial_angle_spread;
float _final_angle_spread;
float _initial_angle,_initial_angle_spread;
float _final_angle,_final_angle_spread;
float _angular_velocity,_angular_velocity_spread;
bool _bUseAngularVelocity;
PUBLISHED:
ZSpinParticleFactory(void);
@ -50,6 +51,15 @@ PUBLISHED:
INLINE float get_final_angle(void) const;
INLINE float get_initial_angle_spread(void) const;
INLINE float get_final_angle_spread(void) const;
INLINE void set_angular_velocity(float v);
INLINE float get_angular_velocity(void) const;
INLINE void set_angular_velocity_spread(float spread);
INLINE float get_angular_velocity_spread(void) const;
INLINE void enable_angular_velocity(bool bEnabled);
INLINE bool get_angular_velocity_enabled(void) const;
};
#include "zSpinParticleFactory.I"