66 | function ObjectChangeUtil.loadValuesFromXML(xmlFile, key, node, object, parent, rootNode, i3dMappings) |
67 | XMLUtil.checkDeprecatedXMLElements(xmlFile, "", key.."#collisionActive", key.."#compoundChildActive or #rigidBodyTypeActive") --FS17 to FS19 |
68 | XMLUtil.checkDeprecatedXMLElements(xmlFile, "", key.."#collisionInactive", key.."#compoundChildInactive or #rigidBodyTypeInactive") --FS17 to FS19 |
69 | |
70 | object.parent = parent |
71 | |
72 | object.interpolation = xmlFile:getValue(key.."#interpolation", false) |
73 | object.interpolationTime = xmlFile:getValue(key.."#interpolationTime", 1) |
74 | |
75 | object.values = {} |
76 | |
77 | local entry = ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "parentNode", nil, |
78 | function(parentNode) |
79 | local x, y, z = getWorldTranslation(node) |
80 | local rx, ry, rz = getWorldRotation(node) |
81 | |
82 | link(parentNode, node) |
83 | |
84 | setWorldTranslation(node, x, y, z) |
85 | setWorldRotation(node, rx, ry, rz) |
86 | end, false, nil, rootNode, i3dMappings) |
87 | |
88 | if entry ~= nil then |
89 | if entry.active == nil then |
90 | entry.active = {getParent(object.node)} |
91 | end |
92 | if entry.inactive == nil then |
93 | entry.inactive = {getParent(object.node)} |
94 | end |
95 | end |
96 | |
97 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "translation", |
98 | function() |
99 | return getTranslation(node) |
100 | end, |
101 | function(x, y, z) |
102 | setTranslation(node, x, y, z) |
103 | end, |
104 | true, nil, true) |
105 | |
106 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "rotation", |
107 | function() |
108 | return getRotation(node) |
109 | end, |
110 | function(x, y, z) |
111 | setRotation(node, x, y, z) |
112 | end, |
113 | true, nil, true) |
114 | |
115 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "scale", |
116 | function() |
117 | return getScale(node) |
118 | end, |
119 | function(x, y, z) |
120 | setScale(node, x, y, z) |
121 | end, |
122 | true, nil, true) |
123 | |
124 | local shaderParameter = xmlFile:getValue(key.."#shaderParameter") |
125 | if shaderParameter ~= nil then |
126 | if getHasShaderParameter(node, shaderParameter) then |
127 | local sharedShaderParameter = xmlFile:getValue(key.."#sharedShaderParameter", false) |
128 | |
129 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "shaderParameter", |
130 | function() |
131 | return getShaderParameter(node, shaderParameter) |
132 | end, |
133 | function(x, y, z, w) |
134 | setShaderParameter(node, shaderParameter, x, y, z, w, sharedShaderParameter) |
135 | end, |
136 | true, nil, true) |
137 | else |
138 | Logging.xmlWarning(xmlFile, "Missing shader parameter '%s' on object '%s' in '%s'", shaderParameter, getName(node), key) |
139 | end |
140 | end |
141 | |
142 | |
143 | local centerOfMassMaskActive = xmlFile:getString(key.."#centerOfMassActive") |
144 | local centerOfMassMaskInactive = xmlFile:getString(key.."#centerOfMassInactive") |
145 | if centerOfMassMaskActive ~= nil or centerOfMassMaskInactive ~= nil then |
146 | centerOfMassMaskActive = (centerOfMassMaskActive or ""):split(" ") |
147 | centerOfMassMaskInactive = (centerOfMassMaskInactive or ""):split(" ") |
148 | |
149 | object.centerOfMassMask = {1, 1, 1} |
150 | object.centerOfMassMaskActive = false |
151 | for i=1, 3 do |
152 | if centerOfMassMaskActive ~= nil and centerOfMassMaskActive[i] == "-" then |
153 | object.centerOfMassMask[i] = 0 |
154 | object.centerOfMassMaskActive = true |
155 | end |
156 | |
157 | if centerOfMassMaskInactive ~= nil and centerOfMassMaskInactive[i] == "-" then |
158 | object.centerOfMassMask[i] = 0 |
159 | object.centerOfMassMaskActive = true |
160 | end |
161 | end |
162 | end |
163 | |
164 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "centerOfMass", |
165 | function() |
166 | return getCenterOfMass(node) |
167 | end, |
168 | function(x, y, z) |
169 | if object.centerOfMassMaskActive ~= nil then |
170 | local cx, cy, cz = getCenterOfMass(node) |
171 | if object.centerOfMassMask[1] == 0 then x = cx end |
172 | if object.centerOfMassMask[2] == 0 then y = cy end |
173 | if object.centerOfMassMask[3] == 0 then z = cz end |
174 | end |
175 | |
176 | setCenterOfMass(node, x, y, z) |
177 | end, |
178 | true, nil, true) |
179 | |
180 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "mass", |
181 | function() |
182 | return getMass(node) |
183 | end, |
184 | function(value) |
185 | setMass(node, value / 1000) |
186 | |
187 | if parent ~= nil and parent.components ~= nil then |
188 | for _, component in ipairs(parent.components) do |
189 | if component.node == object.node then |
190 | component.defaultMass = object.massActive |
191 | parent:setMassDirty() |
192 | end |
193 | end |
194 | end |
195 | end, true) |
196 | |
197 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "visibility", nil, |
198 | function(state) |
199 | setVisibility(node, state) |
200 | end, false) |
201 | |
202 | ObjectChangeUtil.loadValueType(object.values, xmlFile, key, "compoundChild", nil, |
203 | function(state) |
204 | setIsCompoundChild(node, state) |
205 | end, false) |
206 | |
207 | local rigidBodyTypeActiveStr = xmlFile:getValue(key.."#rigidBodyTypeActive") |
208 | if rigidBodyTypeActiveStr ~= nil then |
209 | object.rigidBodyTypeActive = RigidBodyType[rigidBodyTypeActiveStr:upper()] |
210 | |
211 | local t = object.rigidBodyTypeActive |
212 | if t ~= RigidBodyType.STATIC and t ~= RigidBodyType.DYNAMIC and t ~= RigidBodyType.KINEMATIC and t ~= RigidBodyType.NONE then |
213 | Logging.xmlWarning(xmlFile, "Invalid rigidBodyTypeActive '%s' for object change node '%s'. Use 'Static', 'Dynamic', 'Kinematic' or 'None'!", rigidBodyTypeActiveStr, key) |
214 | object.rigidBodyTypeActive = nil |
215 | end |
216 | end |
217 | |
218 | local rigidBodyTypeInactiveStr = xmlFile:getValue(key.."#rigidBodyTypeInactive") |
219 | if rigidBodyTypeInactiveStr ~= nil then |
220 | object.rigidBodyTypeInactive = RigidBodyType[rigidBodyTypeInactiveStr:upper()] |
221 | |
222 | local t = object.rigidBodyTypeInactive |
223 | if t ~= RigidBodyType.STATIC and t ~= RigidBodyType.DYNAMIC and t ~= RigidBodyType.KINEMATIC and t ~= RigidBodyType.NONE then |
224 | Logging.xmlWarning(xmlFile, "Invalid rigidBodyTypeInactive '%s' for object change node '%s'. Use 'Static', 'Dynamic', 'Kinematic' or 'None'!", rigidBodyTypeInactiveStr, key) |
225 | object.rigidBodyTypeInactive = nil |
226 | end |
227 | end |
228 | |
229 | if parent ~= nil and parent.loadObjectChangeValuesFromXML ~= nil then |
230 | parent:loadObjectChangeValuesFromXML(xmlFile, key, node, object) |
231 | end |
232 | end |
364 | function ObjectChangeUtil.registerObjectChangeSingleXMLPaths(schema, basePath) |
365 | schema:addDelayedRegistrationPath(basePath .. ".objectChange(?)", "ObjectChange") |
366 | |
367 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".objectChange(?)#node", "Object change node") |
368 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#interpolation", "Value will be interpolated", false) |
369 | schema:register(XMLValueType.TIME, basePath .. ".objectChange(?)#interpolationTime", "Time for interpolation", 1) |
370 | |
371 | local positivStr = "%s if object change is active" |
372 | local negativeStr = "%s if object change is in active" |
373 | |
374 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#visibilityActive", string.format(positivStr, "visibility")) |
375 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#visibilityInactive", string.format(negativeStr, "visibility")) |
376 | |
377 | schema:register(XMLValueType.VECTOR_TRANS, basePath .. ".objectChange(?)#translationActive", string.format(positivStr, "translation")) |
378 | schema:register(XMLValueType.VECTOR_TRANS, basePath .. ".objectChange(?)#translationInactive", string.format(negativeStr, "translation")) |
379 | |
380 | schema:register(XMLValueType.VECTOR_ROT, basePath .. ".objectChange(?)#rotationActive", string.format(positivStr, "rotation")) |
381 | schema:register(XMLValueType.VECTOR_ROT, basePath .. ".objectChange(?)#rotationInactive", string.format(negativeStr, "rotation")) |
382 | |
383 | schema:register(XMLValueType.VECTOR_SCALE, basePath .. ".objectChange(?)#scaleActive", string.format(positivStr, "scale")) |
384 | schema:register(XMLValueType.VECTOR_SCALE, basePath .. ".objectChange(?)#scaleInactive", string.format(negativeStr, "scale")) |
385 | |
386 | schema:register(XMLValueType.STRING, basePath .. ".objectChange(?)#shaderParameter", "Shader parameter name") |
387 | schema:register(XMLValueType.VECTOR_4, basePath .. ".objectChange(?)#shaderParameterActive", string.format(positivStr, "shaderParameter")) |
388 | schema:register(XMLValueType.VECTOR_4, basePath .. ".objectChange(?)#shaderParameterInactive", string.format(negativeStr, "shaderParameter")) |
389 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#sharedShaderParameter", "Shader parameter is applied on all objects with the same material", false) |
390 | |
391 | schema:register(XMLValueType.FLOAT, basePath .. ".objectChange(?)#massActive", string.format(positivStr, "mass")) |
392 | schema:register(XMLValueType.FLOAT, basePath .. ".objectChange(?)#massInactive", string.format(negativeStr, "mass")) |
393 | |
394 | schema:register(XMLValueType.VECTOR_3, basePath .. ".objectChange(?)#centerOfMassActive", string.format(positivStr, "center of mass")) |
395 | schema:register(XMLValueType.VECTOR_3, basePath .. ".objectChange(?)#centerOfMassInactive", string.format(negativeStr, "center of mass")) |
396 | |
397 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#compoundChildActive", string.format(positivStr, "compound child state")) |
398 | schema:register(XMLValueType.BOOL, basePath .. ".objectChange(?)#compoundChildInactive", string.format(negativeStr, "compound child state")) |
399 | |
400 | schema:register(XMLValueType.STRING, basePath .. ".objectChange(?)#rigidBodyTypeActive", string.format(positivStr, "rigid body type")) |
401 | schema:register(XMLValueType.STRING, basePath .. ".objectChange(?)#rigidBodyTypeInactive", string.format(negativeStr, "rigid body type")) |
402 | |
403 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".objectChange(?)#parentNodeActive", string.format(positivStr, "parent node")) |
404 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".objectChange(?)#parentNodeInactive", string.format(negativeStr, "parent node")) |
405 | end |
254 | function ObjectChangeUtil.setObjectChange(object, isActive, target, updateFunc, skipInterpolation) |
255 | if isActive then |
256 | for i=1, #object.values do |
257 | local value = object.values[i] |
258 | |
259 | if value.active ~= nil then |
260 | if object.interpolation and value.interpolatable and not skipInterpolation then |
261 | local interpolator = ValueInterpolator.new(object.node .. value.name, value.getFunc, value.setFunc, value.active, object.interpolationTime) |
262 | if interpolator ~= nil then |
263 | interpolator:setUpdateFunc(updateFunc, target, object.node) |
264 | interpolator:setDeleteListenerObject(target or object.parent) |
265 | end |
266 | else |
267 | if skipInterpolation then |
268 | ValueInterpolator.removeInterpolator(object.node .. value.name) |
269 | end |
270 | |
271 | value.setFunc(unpack(value.active)) |
272 | end |
273 | end |
274 | end |
275 | |
276 | if object.rigidBodyTypeActive ~= nil then |
277 | setRigidBodyType(object.node, object.rigidBodyTypeActive) |
278 | end |
279 | else |
280 | for i=1, #object.values do |
281 | local value = object.values[i] |
282 | |
283 | if value.inactive ~= nil then |
284 | if object.interpolation and value.interpolatable and not skipInterpolation then |
285 | local interpolator = ValueInterpolator.new(object.node .. value.name, value.getFunc, value.setFunc, value.inactive, object.interpolationTime) |
286 | if interpolator ~= nil then |
287 | interpolator:setUpdateFunc(updateFunc, target, object.node) |
288 | interpolator:setDeleteListenerObject(target or object.parent) |
289 | end |
290 | else |
291 | if skipInterpolation then |
292 | ValueInterpolator.removeInterpolator(object.node .. value.name) |
293 | end |
294 | |
295 | value.setFunc(unpack(value.inactive)) |
296 | end |
297 | end |
298 | end |
299 | |
300 | if object.rigidBodyTypeInactive ~= nil then |
301 | setRigidBodyType(object.node, object.rigidBodyTypeInactive) |
302 | end |
303 | end |
304 | if target ~= nil then |
305 | if target.setObjectChangeValues ~= nil then |
306 | target:setObjectChangeValues(object, isActive) |
307 | end |
308 | if updateFunc ~= nil then |
309 | updateFunc(target, object.node) |
310 | end |
311 | end |
312 | end |