22 | function JigglingParts.initSpecialization() |
23 | local schema = Vehicle.xmlSchema |
24 | schema:setXMLSpecializationType("JigglingParts") |
25 | |
26 | local basePath = JigglingParts.JIGGLING_PART_XML_KEY |
27 | schema:register(XMLValueType.NODE_INDEX, basePath .. "#node", "Jiggling node") |
28 | |
29 | schema:register(XMLValueType.FLOAT, basePath .. "#speedScale", "Speed scale", 1) |
30 | schema:register(XMLValueType.STRING, basePath .. "#shaderParameter", "Shader parameter", "amplFreq") |
31 | schema:register(XMLValueType.STRING, basePath .. "#shaderParameterPrev", "Shader parameter previous frame", "prevAmplFreq") |
32 | schema:register(XMLValueType.INT, basePath .. "#shaderParameterComponentSpeed", "Shader component speed index", 4) |
33 | schema:register(XMLValueType.INT, basePath .. "#shaderParameterComponentAmplitude", "Shader component amplitude index", 1) |
34 | schema:register(XMLValueType.FLOAT, basePath .. "#amplitudeScale", "Amplitude scale", 4) |
35 | schema:register(XMLValueType.INT, basePath .. "#refNodeIndex", "Ground reference node index") |
36 | |
37 | schema:setXMLSpecializationType() |
38 | end |
124 | function JigglingParts:isJigglingPartActive(jigglingPart) |
125 | if jigglingPart.refNodeIndex ~= nil and jigglingPart.refNode == nil then |
126 | if self.getGroundReferenceNodeFromIndex ~= nil then |
127 | local refNode = self:getGroundReferenceNodeFromIndex(jigglingPart.refNodeIndex) |
128 | if refNode ~= nil then |
129 | jigglingPart.refNode = refNode |
130 | end |
131 | end |
132 | |
133 | if jigglingPart.refNode == nil then |
134 | Logging.xmlWarning(self.xmlFile, "Unable to find ground reference node '%d' for jiggling part '%s'", jigglingPart.refNodeIndex, getName(jigglingPart.node)) |
135 | end |
136 | |
137 | jigglingPart.refNodeIndex = nil |
138 | end |
139 | |
140 | |
141 | if jigglingPart.refNode ~= nil then |
142 | if not self:getIsGroundReferenceNodeActive(jigglingPart.refNode) then |
143 | return false |
144 | end |
145 | end |
146 | |
147 | return true |
148 | end |
96 | function JigglingParts:loadJigglingPartsFromXML(jigglingPart, xmlFile, key) |
97 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. "#index", key .. "#node") --FS17 to FS19 |
98 | |
99 | jigglingPart.currentTime = 0 |
100 | jigglingPart.currentAmplitudeScale = 0 |
101 | |
102 | jigglingPart.node = xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings) |
103 | if jigglingPart.node == nil then |
104 | Logging.xmlWarning(self.xmlFile, "Failed to load node for jiggling part '%s'", key) |
105 | return false |
106 | end |
107 | |
108 | jigglingPart.speedScale = xmlFile:getValue(key .. "#speedScale", 1) |
109 | jigglingPart.shaderParameter = xmlFile:getValue(key .. "#shaderParameter", "amplFreq") |
110 | jigglingPart.shaderParameterPrev = xmlFile:getValue(key .. "#shaderParameterPrev", "prevAmplFreq") |
111 | jigglingPart.shaderParameterComponentSpeed = xmlFile:getValue(key .. "#shaderParameterComponentSpeed", 4) |
112 | jigglingPart.shaderParameterComponentAmplitude = xmlFile:getValue(key .. "#shaderParameterComponentAmplitude", 1) |
113 | jigglingPart.amplitudeScale = xmlFile:getValue(key .. "#amplitudeScale", 4.0) |
114 | |
115 | jigglingPart.refNodeIndex = xmlFile:getValue(key .. "#refNodeIndex") |
116 | |
117 | jigglingPart.values = {0, 0, 0, 0} |
118 | |
119 | return true |
120 | end |
57 | function JigglingParts:onLoad(savegame) |
58 | local spec = self.spec_jigglingParts |
59 | |
60 | spec.parts = {} |
61 | local i = 0 |
62 | while true do |
63 | local key = string.format("vehicle.jigglingParts.jigglingPart(%d)", i) |
64 | if not self.xmlFile:hasProperty(key) then |
65 | break |
66 | end |
67 | |
68 | local jigglingPart = {} |
69 | if self:loadJigglingPartsFromXML(jigglingPart, self.xmlFile, key) then |
70 | table.insert(spec.parts, jigglingPart) |
71 | end |
72 | |
73 | i = i + 1 |
74 | end |
75 | |
76 | if #spec.parts == 0 then |
77 | SpecializationUtil.removeEventListener(self, "onUpdate", JigglingParts) |
78 | end |
79 | end |
83 | function JigglingParts:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
84 | local spec = self.spec_jigglingParts |
85 | for _, jigglingPart in ipairs(spec.parts) do |
86 | if self:isJigglingPartActive(jigglingPart) then |
87 | self:updateJigglingPart(jigglingPart, dt, true) |
88 | elseif jigglingPart.currentAmplitudeScale > 0 then |
89 | self:updateJigglingPart(jigglingPart, dt, false) |
90 | end |
91 | end |
92 | end |
152 | function JigglingParts:updateJigglingPart(jigglingPart, dt, groundContact) |
153 | local oldX, oldY, oldZ, oldW = jigglingPart.values[1], jigglingPart.values[2], jigglingPart.values[3], jigglingPart.values[4] |
154 | local x, y, z, w = getShaderParameter(jigglingPart.node, jigglingPart.shaderParameter) |
155 | jigglingPart.values[1], jigglingPart.values[2], jigglingPart.values[3], jigglingPart.values[4] = x, y, z, w |
156 | |
157 | -- update speed |
158 | local t = dt / 1000 * jigglingPart.speedScale * self:getLastSpeed() / 20 |
159 | jigglingPart.currentTime = jigglingPart.currentTime + t |
160 | jigglingPart.values[jigglingPart.shaderParameterComponentSpeed] = jigglingPart.currentTime |
161 | |
162 | --update amplitude |
163 | if groundContact and jigglingPart.currentAmplitudeScale < 1 then |
164 | jigglingPart.currentAmplitudeScale = math.min(jigglingPart.currentAmplitudeScale + dt / 100, 1) |
165 | elseif not groundContact and jigglingPart.currentAmplitudeScale > 0 then |
166 | jigglingPart.currentAmplitudeScale = math.max(jigglingPart.currentAmplitudeScale - dt / 100, 0) |
167 | end |
168 | jigglingPart.values[jigglingPart.shaderParameterComponentAmplitude] = jigglingPart.currentAmplitudeScale * jigglingPart.amplitudeScale |
169 | |
170 | setShaderParameter(jigglingPart.node, jigglingPart.shaderParameter, jigglingPart.values[1], jigglingPart.values[2], jigglingPart.values[3], jigglingPart.values[4], false) |
171 | setShaderParameter(jigglingPart.node, jigglingPart.shaderParameterPrev, oldX, oldY, oldZ, oldW, false) |
172 | end |