96 | function Leveler:update(dt) |
97 | if self:getIsActive() then |
98 | if self.isClient then |
99 | local fillType = self:getUnitFillType(self.leveler.fillUnitIndex); |
100 | local visible = self:getUnitFillLevel(self.leveler.fillUnitIndex) > 2*TipUtil.getMinValidLiterValue(fillType); |
101 | if visible and fillType ~= FillUtil.FILLTYPE_UNKNOWN then |
102 | EffectManager:setFillType(self.leveler.effects, fillType) |
103 | EffectManager:startEffects(self.leveler.effects); |
104 | |
105 | local fillPercentage =self:getUnitFillLevel(self.leveler.fillUnitIndex) / self:getUnitCapacity(self.leveler.fillUnitIndex); |
106 | |
107 | for _,effect in pairs(self.leveler.effects) do |
108 | if effect.depthTarget ~= nil then |
109 | |
110 | if effect.depthTarget < fillPercentage then |
111 | effect.depthTarget = math.min(fillPercentage, effect.depthTarget + 0.001*dt); |
112 | elseif effect.depthTarget > fillPercentage then |
113 | effect.depthTarget = math.max(fillPercentage, effect.depthTarget - 0.001*dt); |
114 | end |
115 | |
116 | local speed = self.movingDirection * effect.speed * self:getLastSpeed(); |
117 | effect.scrollPosition = effect.scrollPosition + speed; |
118 | |
119 | setShaderParameter(effect.node, "VertxoffsetVertexdeformMotionUVscale", effect.maxHeight, effect.depthTarget, effect.scrollPosition, 6.0, false); |
120 | |
121 | setVisibility(effect.node, true); |
122 | end |
123 | end |
124 | else |
125 | EffectManager:stopEffects(self.leveler.effects); |
126 | for _,effect in pairs(self.leveler.effects) do |
127 | if effect.node ~= nil then |
128 | effect.depthTarget = 0; |
129 | effect.scrollPosition = 0; |
130 | setVisibility(effect.node, false); |
131 | end |
132 | end |
133 | end |
134 | end |
135 | end |
136 | |
137 | if self:getIsActive() and self.isServer then |
138 | |
139 | local fillFactor = 1; |
140 | local emptyFactor = 1; |
141 | |
142 | for _,levelerNode in pairs(self.leveler.nodes) do |
143 | |
144 | local pickedUpFillLevel = 0; |
145 | |
146 | local fillType = self:getUnitFillType(self.leveler.fillUnitIndex); |
147 | local fillLevel = self:getUnitFillLevel(self.leveler.fillUnitIndex); |
148 | |
149 | if fillType == FillUtil.FILLTYPE_UNKNOWN or fillLevel < TipUtil.getMinValidLiterValue(fillType) + 0.001 then |
150 | local x0,y0,z0 = localToWorld(levelerNode.node, -levelerNode.width, 0, 0.5*levelerNode.maxDropDirOffset); |
151 | local x1,y1,z1 = localToWorld(levelerNode.node, levelerNode.width, 0, 0.5*levelerNode.maxDropDirOffset); |
152 | |
153 | local newFillType = TipUtil.getFillTypeAtLine(x0,y0,z0, x1,y1,z1, 0.5*levelerNode.maxDropDirOffset); |
154 | if newFillType ~= FillUtil.FILLTYPE_UNKNOWN and newFillType ~= fillType then |
155 | self:setUnitFillLevel(self.leveler.fillUnitIndex, 0); |
156 | fillType = newFillType; |
157 | end |
158 | end |
159 | local heightType = TipUtil.fillTypeToHeightType[fillType]; |
160 | |
161 | |
162 | if fillType ~= FillUtil.FILLTYPE_UNKNOWN and heightType ~= nil then |
163 | |
164 | local innerRadius = 0; |
165 | local outerRadius = TipUtil.getDefaultMaxRadius(fillType); |
166 | |
167 | -- use occlusion areas only, if they are close to the ground |
168 | local tipOcclusionAreas = {}; |
169 | -- temporary disabled |
170 | --for _,area in pairs(self.tipOcclusionAreas) do |
171 | -- local xs,ys,zs = getWorldTranslation(area.start); |
172 | -- local xw,yw,zw = getWorldTranslation(area.width); |
173 | -- local xh,yh,zh = getWorldTranslation(area.height); |
174 | -- |
175 | -- local x1 = xs + 0.5*(xh - xs); |
176 | -- local y1 = ys + 0.5*(yh - ys); |
177 | -- local z1 = zs + 0.5*(zh - zs); |
178 | -- |
179 | -- local x2 = xw + 0.5*(xh - xs); |
180 | -- local y2 = yw + 0.5*(yh - ys); |
181 | -- local z2 = zw + 0.5*(zh - zs); |
182 | -- |
183 | -- local h1 = TipUtil.getHeightAtWorldPos(x1,y1,z1); |
184 | -- local h2 = TipUtil.getHeightAtWorldPos(x2,y2,z2); |
185 | -- |
186 | -- if h1 > y1 - 0.5 and h2 > y2 - 0.5 then |
187 | -- table.insert(tipOcclusionAreas, area); |
188 | -- end |
189 | --end |
190 | |
191 | local capacity = self:getUnitCapacity(self.leveler.fillUnitIndex); |
192 | |
193 | -- pick up at node |
194 | if self:getIsLevelerPickupNodeActive(levelerNode) then |
195 | if self.leveler.pickUpDirection == self.movingDirection then |
196 | local sx,sy,sz = localToWorld(levelerNode.node, -levelerNode.width, 0, 0); |
197 | local ex,ey,ez = localToWorld(levelerNode.node, levelerNode.width, 0, 0); |
198 | |
199 | local fillLevel = self:getUnitFillLevel(self.leveler.fillUnitIndex); |
200 | local delta = -fillFactor * (capacity-fillLevel); |
201 | local numHeightLimitChecks = levelerNode.numHeightLimitChecks; |
202 | if numHeightLimitChecks > 0 then |
203 | local movementY = 0; |
204 | for i=0,numHeightLimitChecks do |
205 | local t = i/numHeightLimitChecks |
206 | local xi = sx + (ex-sx)*t; |
207 | local yi = sy + (ey-sy)*t; |
208 | local zi = sz + (ez-sz)*t; |
209 | local hi = TipUtil.getHeightAtWorldPos(xi,yi,zi); |
210 | movementY = math.max(movementY, hi-0.05 - yi); -- limit to 5cm below surface |
211 | end |
212 | if movementY > 0 then |
213 | sy = sy+movementY; |
214 | ey = ey+movementY; |
215 | end |
216 | end |
217 | |
218 | levelerNode.lastPickUp, levelerNode.lineOffsetPickUp = TipUtil.tipToGroundAroundLine(self, delta, fillType, sx,sy-0.1,sz, ex,ey-0.1,ez, innerRadius, outerRadius, levelerNode.lineOffsetPickUp, true, nil); |
219 | |
220 | if levelerNode.lastPickUp < 0 then |
221 | self:setUnitFillLevel(self.leveler.fillUnitIndex, fillLevel - levelerNode.lastPickUp, fillType, nil, nil); |
222 | pickedUpFillLevel = levelerNode.lastPickUp; |
223 | end |
224 | end |
225 | end |
226 | |
227 | -- drop at node |
228 | local fillLevel = self:getUnitFillLevel(self.leveler.fillUnitIndex); |
229 | if fillLevel > 0 then |
230 | local f = (fillLevel/capacity); |
231 | local width = Utils.lerp(levelerNode.minDropWidth, levelerNode.maxDropWidth, f); |
232 | |
233 | local sx,sy,sz = localToWorld(levelerNode.node, -width, 0, 0); |
234 | local ex,ey,ez = localToWorld(levelerNode.node, width, 0, 0); |
235 | |
236 | local delta = math.min(fillLevel, emptyFactor * fillLevel); |
237 | local yOffset = -0.1 -0.05; |
238 | |
239 | levelerNode.lastDrop1, levelerNode.lineOffsetDrop1 = TipUtil.tipToGroundAroundLine(self, delta, fillType, sx,sy+yOffset,sz, ex,ey+yOffset,ez, innerRadius, outerRadius, levelerNode.lineOffsetDrop1, true, tipOcclusionAreas); |
240 | if levelerNode.lastDrop1 > 0 then |
241 | self:setUnitFillLevel(self.leveler.fillUnitIndex, fillLevel - levelerNode.lastDrop1, fillType, nil, nil); |
242 | end |
243 | end |
244 | |
245 | -- drop further at front |
246 | local fillLevel = self:getUnitFillLevel(self.leveler.fillUnitIndex); |
247 | |
248 | if fillLevel > 0 then |
249 | local f = (fillLevel/capacity); |
250 | local width = Utils.lerp(levelerNode.minDropWidth, levelerNode.maxDropWidth, f); |
251 | |
252 | local yOffset = Utils.lerp(levelerNode.minDropHeight, levelerNode.maxDropHeight, f); |
253 | |
254 | local delta = math.min(fillLevel, emptyFactor * fillLevel); |
255 | |
256 | local sx,sy,sz = localToWorld(levelerNode.node, -width, 0, 0); |
257 | local ex,ey,ez = localToWorld(levelerNode.node, width, 0, 0); |
258 | local dx,dy,dz = localDirectionToWorld(levelerNode.node, 0, 0, 1); |
259 | |
260 | local backOffset = -outerRadius * self.leveler.pickUpDirection * 1.5; |
261 | local backLen = Utils.lerp(levelerNode.minDropDirOffset, levelerNode.maxDropDirOffset, f) - backOffset; |
262 | |
263 | local backX,backY,backZ = dx*backOffset,dy*backOffset,dz*backOffset; |
264 | dx,dy,dz = dx*backLen,dy*backLen,dz*backLen; |
265 | |
266 | |
267 | addDensityMapHeightOcclusionArea(TipUtil.terrainDetailHeightUpdater, sx+backX,sy+backY,sz+backZ, ex-sx,ey-sy,ez-sz, dx, dy, dz, true); |
268 | if width < levelerNode.width-0.05 then |
269 | -- fully block left and right of the inner block area |
270 | local sx2,sy2,sz2 = localToWorld(levelerNode.node, -levelerNode.width, 0, 0); |
271 | local ex2,ey2,ez2 = localToWorld(levelerNode.node, levelerNode.width, 0, 0); |
272 | |
273 | addDensityMapHeightOcclusionArea(TipUtil.terrainDetailHeightUpdater, sx2+backX,sy2+backY,sz2+backZ, sx-sx2,sy-sy2,sz-sz2, dx, dy, dz, false); |
274 | addDensityMapHeightOcclusionArea(TipUtil.terrainDetailHeightUpdater, ex +backX,ey +backY,ez +backZ, ex2-ex,ey2-ey,ez2-ez, dx, dy, dz, false); |
275 | end |
276 | |
277 | |
278 | levelerNode.lastDrop2, levelerNode.lineOffsetDrop2 = TipUtil.tipToGroundAroundLine(self, delta, fillType, sx,sy+yOffset,sz, ex,ey+yOffset,ez, 0, outerRadius, levelerNode.lineOffsetDrop2, true, tipOcclusionAreas); |
279 | if levelerNode.lastDrop2 > 0 then |
280 | self:setUnitFillLevel(self.leveler.fillUnitIndex, fillLevel - levelerNode.lastDrop2, fillType, nil, nil); |
281 | end |
282 | |
283 | end |
284 | |
285 | end |
286 | |
287 | if pickedUpFillLevel < 0 and fillType ~= FillUtil.FILLTYPE_UNKNOWN then |
288 | if self.changedFillLevelCallback ~= nil then |
289 | if self.changedFillLevelCallbackTarget ~= nil then |
290 | self.changedFillLevelCallback(self.changedFillLevelCallbackTarget, self, pickedUpFillLevel, fillType) |
291 | else |
292 | self.changedFillLevelCallback(self, pickedUpFillLevel, fillType) |
293 | end |
294 | end |
295 | end |
296 | |
297 | end |
298 | |
299 | end |
300 | end |