21 | function ParticleEffect:loadEffectAttributes(xmlFile, key, node, i3dNode, i3dMapping) |
22 | if not ParticleEffect:superClass().loadEffectAttributes(self, xmlFile, key, node, i3dNode, i3dMapping) then |
23 | return false |
24 | end |
25 | |
26 | self.emitterShape = self.node |
27 | |
28 | self.emitterShapeTrans = createTransformGroup("emitterShapeTrans") |
29 | link(getParent(self.emitterShape), self.emitterShapeTrans, getChildIndex(self.emitterShape)) |
30 | link(self.emitterShapeTrans, self.emitterShape) |
31 | |
32 | self.emitCountScale = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLFloat, node, "emitCountScale"), 1) |
33 | self.particleType = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLString, node, "particleType"), "unloading") |
34 | self.worldSpace = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLBool, node, "worldSpace"), true) |
35 | self.delay = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLFloat, node, "delay"), 0) |
36 | self.startTime = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLFloat, node, "startTime"), self.delay) |
37 | self.startTimeMs = self.startTime*1000 |
38 | self.stopTime = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLFloat, node, "stopTime"), self.delay) |
39 | self.stopTimeMs = self.stopTime*1000 |
40 | self.lifespan = Effect.getValue(xmlFile, key, getXMLFloat, node, "lifespan") |
41 | self.extraDistance = Effect.getValue(xmlFile, key, getXMLFloat, node, "extraDistance") or 0 |
42 | |
43 | self.realStartTime = -math.huge |
44 | self.realStopTime = math.huge |
45 | |
46 | self.useCuttingWidth = Utils.getNoNil(Effect.getValue(xmlFile, key, getXMLBool, node, "useCuttingWidth"), true) |
47 | |
48 | self.currentParticleSystem = nil |
49 | self.particleSystems = {} |
50 | |
51 | return true |
52 | end |
192 | function ParticleEffect:setDistance(distance, terrain) |
193 | if self.currentParticleSystem ~= nil then |
194 | if not self.currentParticleSystem.forceFullLifespan then |
195 | local _, dirY, _ = localDirectionToWorld(self.currentParticleSystem.emitterShape, 0, 1, 0) |
196 | local direction = dirY / 1 |
197 | |
198 | local index = math.floor(direction*#self.distanceToLifespans) |
199 | local curve = self.distanceToLifespans[MathUtil.clamp(index, 1, #self.distanceToLifespans)] |
200 | |
201 | local lifespan = curve:get(distance+self.extraDistance) |
202 | ParticleUtil.setParticleLifespan(self.currentParticleSystem, lifespan) |
203 | end |
204 | end |
205 | end |
99 | function ParticleEffect:setFillType(fillType) |
100 | local success = true |
101 | if self.currentFillType ~= fillType then |
102 | local wasActive = false |
103 | if self.currentParticleSystem ~= nil then |
104 | wasActive = true |
105 | ParticleUtil.setEmittingState(self.currentParticleSystem, false) |
106 | self.currentParticleSystem = nil |
107 | end |
108 | |
109 | if self.particleSystems[fillType] == nil then |
110 | local particleSystem = g_particleSystemManager:getParticleSystem(fillType, self.particleType) |
111 | if particleSystem ~= nil then |
112 | local psClone = clone( particleSystem.shape, true, false, true ) |
113 | local currentPS = {} |
114 | local emitterShape = self.emitterShape |
115 | ParticleUtil.loadParticleSystemFromNode(psClone, currentPS, false, self.worldSpace, particleSystem.forceFullLifespan) |
116 | self.particleSystems[fillType] = currentPS |
117 | |
118 | ParticleUtil.setEmitterShape(self.particleSystems[fillType], emitterShape) |
119 | local scale = (currentPS.emitterShapeSize/currentPS.defaultEmitterShapeSize)*self.emitCountScale |
120 | ParticleUtil.initEmitterScale(currentPS, scale) |
121 | |
122 | ParticleUtil.setEmitCountScale(currentPS, 1) |
123 | if self.lifespan ~= nil then |
124 | ParticleUtil.setParticleLifespan(currentPS, self.lifespan*1000) |
125 | currentPS.originalLifespan = self.lifespan*1000 |
126 | end |
127 | ParticleUtil.setParticleStartStopTime(currentPS, self.startTime, self.stopTime) |
128 | |
129 | if not currentPS.worldSpace then |
130 | link(getParent(emitterShape), currentPS.shape, getChildIndex(emitterShape)) |
131 | setTranslation(currentPS.shape, getTranslation(emitterShape)) |
132 | setRotation(currentPS.shape, getRotation(emitterShape)) |
133 | link(currentPS.shape, emitterShape) |
134 | setTranslation(emitterShape, 0,0,0) |
135 | setRotation(emitterShape, 0,0,0) |
136 | end |
137 | else |
138 | success = false |
139 | end |
140 | end |
141 | |
142 | self.currentParticleSystem = self.particleSystems[fillType] |
143 | |
144 | if wasActive then |
145 | ParticleUtil.setEmittingState(self.currentParticleSystem, true) |
146 | end |
147 | |
148 | -- precalculate the lifespans depending on the normal speed of the particleSystem |
149 | -- calculation is depending on the y direction of the emitter shape |
150 | if self.currentParticleSystem ~= nil then |
151 | self.distanceToLifespans = {} |
152 | for j=0, 1, 0.1 do |
153 | local invJ = 1-j |
154 | local lifespans = AnimCurve:new(linearInterpolator1) |
155 | for i=1, 20 do |
156 | local lifespan = i * 100 |
157 | local normalSpeed, _ = getParticleSystemAverageSpeed(self.currentParticleSystem.geometry) |
158 | local gravity = 1.5 * 0.00000478 |
159 | local distance = normalSpeed * lifespan * invJ + (gravity * lifespan * lifespan) |
160 | lifespans:addKeyframe({lifespan, time=distance}) |
161 | end |
162 | |
163 | table.insert(self.distanceToLifespans, lifespans) |
164 | end |
165 | end |
166 | end |
167 | |
168 | return success |
169 | end |
173 | function ParticleEffect:setMinMaxWidth(minValue, maxValue, reset) |
174 | if self.useCuttingWidth then |
175 | local widthX = math.abs(minValue-maxValue) |
176 | local emitterShape = self.emitterShape |
177 | local _,sy,sz = getScale(emitterShape) |
178 | setScale(emitterShape, widthX, sy, sz) |
179 | local _,y,z = getTranslation(emitterShape) |
180 | setTranslation(emitterShape, -(maxValue - widthX*0.5), y, z) |
181 | ParticleUtil.setEmitCountScale(self.currentParticleSystem, widthX) |
182 | self.totalWidth = widthX |
183 | |
184 | if self.isActive then |
185 | ParticleUtil.setEmittingState(self.currentParticleSystem, widthX > 0) |
186 | end |
187 | end |
188 | end |