LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

ConnectionHoses

Description
Specialization for connection hoses between vehicles and tools
Functions

addHoseTargetNodes

Description
Definition
addHoseTargetNodes()
Code
639function ConnectionHoses:addHoseTargetNodes(xmlFile, key)
640 local spec = self.spec_connectionHoses
641
642 local addedTarget = false
643 xmlFile:iterate(key, function(_, targetKey)
644 local entry = {}
645 if self:loadHoseTargetNode(xmlFile, targetKey, entry) then
646 table.insert(spec.targetNodes, entry)
647 entry.index = #spec.targetNodes
648
649 if spec.targetNodesByType[entry.type] == nil then
650 spec.targetNodesByType[entry.type] = {}
651 end
652
653 table.insert(spec.targetNodesByType[entry.type], entry)
654 addedTarget = true
655 end
656 end)
657
658 -- return the index of the last added target
659 if addedTarget then
660 return #spec.targetNodes
661 end
662end

addHoseToDelayedMountings

Description
Definition
addHoseToDelayedMountings()
Code
1351function ConnectionHoses:addHoseToDelayedMountings(sourceObject, sourceHose, targetObject, targetHose)
1352 local spec = self.spec_connectionHoses
1353
1354 local toolConnectionHose = spec.targetNodeToToolConnection[targetHose.index]
1355 if toolConnectionHose ~= nil and (toolConnectionHose.delayedMounting == nil or sourceHose.typedIndex == toolConnectionHose.typedIndex) then
1356 local retry = toolConnectionHose.delayedMounting == nil
1357 toolConnectionHose.delayedMounting = {sourceObject=sourceObject, sourceHose=sourceHose, targetObject=targetObject, targetHose=targetHose}
1358
1359 if retry then
1360 self.rootVehicle:retryHoseSkipNodeConnections(true, sourceObject)
1361 end
1362 end
1363end

connectCustomHoseNode

Description
Definition
connectCustomHoseNode()
Code
1539function ConnectionHoses:connectCustomHoseNode(customHose, customTarget)
1540 self:updateCustomHoseNode(customHose, customTarget)
1541
1542 customHose.isActive = true
1543 customTarget.isActive = true
1544
1545 customHose.connectedTarget = customTarget
1546 customTarget.connectedHose = customHose
1547
1548 ObjectChangeUtil.setObjectChanges(customHose.objectChanges, true)
1549 ObjectChangeUtil.setObjectChanges(customTarget.objectChanges, true)
1550end

connectCustomHosesToAttacherVehicle

Description
Definition
connectCustomHosesToAttacherVehicle()
Code
1488function ConnectionHoses:connectCustomHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex)
1489 local spec = self.spec_connectionHoses
1490 local customHoses = spec.customHosesByInputAttacher[inputJointDescIndex]
1491 if customHoses ~= nil then
1492 for i=1, #customHoses do
1493 local customHose = customHoses[i]
1494 if not customHose.isActive then
1495 if attacherVehicle.spec_connectionHoses ~= nil then
1496 local customTargets = attacherVehicle.spec_connectionHoses.customHoseTargetsByAttacher[jointDescIndex]
1497 if customTargets ~= nil then
1498 for j=1, #customTargets do
1499 local customTarget = customTargets[j]
1500 if not customTarget.isActive then
1501 if customHose.type == customTarget.type
1502 and customHose.specType == customTarget.specType then
1503 self:connectCustomHoseNode(customHose, customTarget)
1504 end
1505 end
1506 end
1507 end
1508 end
1509 end
1510 end
1511 end
1512
1513 local customTargets = spec.customHoseTargetsByInputAttacher[inputJointDescIndex]
1514 if customTargets ~= nil then
1515 for i=1, #customTargets do
1516 local customTarget = customTargets[i]
1517 if not customTarget.isActive then
1518 if attacherVehicle.spec_connectionHoses ~= nil then
1519 customHoses = attacherVehicle.spec_connectionHoses.customHosesByAttacher[jointDescIndex]
1520 if customHoses ~= nil then
1521 for j=1, #customHoses do
1522 local customHose = customHoses[j]
1523 if not customHose.isActive then
1524 if customHose.type == customTarget.type
1525 and customHose.specType == customTarget.specType then
1526 self:connectCustomHoseNode(customHose, customTarget)
1527 end
1528 end
1529 end
1530 end
1531 end
1532 end
1533 end
1534 end
1535end

connectHose

Description
Definition
connectHose()
Code
1110function ConnectionHoses:connectHose(sourceHose, targetObject, targetHose, updateToolConnections)
1111 local spec = self.spec_connectionHoses
1112
1113 local doConnect = false
1114 if updateToolConnections ~= nil and not updateToolConnections then
1115 doConnect = true
1116 else
1117 if targetObject:updateToolConnectionHose(self, sourceHose, targetObject, targetHose, true) then
1118 doConnect = true
1119 else
1120 -- on tool connections we wait until both ends are connected to a tool and then we connect the hoses
1121 targetObject:addHoseToDelayedMountings(self, sourceHose, targetObject, targetHose)
1122 end
1123 end
1124
1125 if doConnect then
1126 targetHose.connectedObject = self
1127 sourceHose.connectedObject = targetObject
1128
1129 sourceHose.targetHose = targetHose
1130
1131 local node, referenceNode
1132 if sourceHose.adapterName ~= nil then
1133 if sourceHose.adapterName ~= "NONE" then
1134 node, referenceNode = g_connectionHoseManager:getClonedAdapterNode(targetHose.type, sourceHose.adapterName, self.customEnvironment)
1135 end
1136 elseif targetHose.adapterName ~= "NONE" then
1137 node, referenceNode = g_connectionHoseManager:getClonedAdapterNode(targetHose.type, targetHose.adapterName, self.customEnvironment)
1138 end
1139
1140 if node ~= nil then
1141 link(g_connectionHoseManager:getSocketTarget(targetHose.socket, targetHose.node), node)
1142 setTranslation(node, 0,0,0)
1143 setRotation(node, 0,0,0)
1144 targetObject:addAllSubWashableNodes(node)
1145
1146 targetHose.adapter.node = node
1147 targetHose.adapter.refNode = referenceNode
1148 targetHose.adapter.isLinked = true
1149 end
1150
1151 sourceHose.targetNode = targetHose.adapter.refNode
1152
1153 setVisibility(sourceHose.visibilityNode, true)
1154 setShaderParameter(sourceHose.hoseNode, "cv0", 0, 0, -sourceHose.startStraightening, 1, false)
1155 sourceHose.endStraightening = sourceHose.endStraighteningBase * targetHose.straighteningFactor
1156 sourceHose.endStraighteningDirection = targetHose.straighteningDirection or sourceHose.endStraighteningDirectionBase
1157
1158 ObjectChangeUtil.setObjectChanges(targetHose.objectChanges, true)
1159 ObjectChangeUtil.setObjectChanges(sourceHose.objectChanges, true)
1160
1161 g_connectionHoseManager:openSocket(sourceHose.socket)
1162 g_connectionHoseManager:openSocket(targetHose.socket)
1163
1164 self:updateConnectionHose(sourceHose, 0)
1165
1166 table.insert(spec.updateableHoses, sourceHose)
1167 return true
1168 end
1169
1170 return false
1171end

connectHosesToAttacherVehicle

Description
Definition
connectHosesToAttacherVehicle()
Code
1441function ConnectionHoses:connectHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex, updateToolConnections, excludeVehicle)
1442 if attacherVehicle.getConnectionTarget ~= nil then
1443 local hoses = self:getConnectionHosesByInputAttacherJoint(inputJointDescIndex)
1444 for _, hose in ipairs(hoses) do
1445 attacherVehicle:iterateConnectionTargets(function(target, isSkipNode)
1446 if not self:getIsConnectionHoseUsed(hose) then
1447 if not isSkipNode then
1448 if self:connectHose(hose, attacherVehicle, target, updateToolConnections) then
1449 return false
1450 end
1451 else
1452 if self:connectHoseToSkipNode(hose, attacherVehicle, target) then
1453 return false
1454 end
1455 end
1456
1457
1458 return true
1459 end
1460
1461 return false
1462 end, jointDescIndex, hose.type, hose.specType)
1463 end
1464
1465 --try to connect the hoses of attached implements, maybe the connection is now valid since we got another skip node
1466 self:retryHoseSkipNodeConnections(updateToolConnections, excludeVehicle)
1467 end
1468end

connectHoseToSkipNode

Description
Definition
connectHoseToSkipNode()
Code
1367function ConnectionHoses:connectHoseToSkipNode(sourceHose, targetObject, skipNode, childHose, childVehicle)
1368 local spec = self.spec_connectionHoses
1369
1370 skipNode.connectedObject = self
1371 sourceHose.connectedObject = targetObject
1372
1373 sourceHose.targetHose = skipNode
1374 sourceHose.targetNode = skipNode.node
1375
1376 setVisibility(sourceHose.visibilityNode, true)
1377 setShaderParameter(sourceHose.hoseNode, "cv0", 0, 0, -sourceHose.startStraightening, 1, false)
1378
1379 ObjectChangeUtil.setObjectChanges(sourceHose.objectChanges, true)
1380
1381 self:addAllSubWashableNodes(sourceHose.hoseNode)
1382
1383 sourceHose.childVehicle = childVehicle
1384 sourceHose.childHose = childHose
1385
1386 if self.getAttacherVehicle ~= nil then
1387 local attacherVehicle1 = self:getAttacherVehicle()
1388 if attacherVehicle1.getAttacherVehicle ~= nil then
1389 local attacherVehicle2 = attacherVehicle1:getAttacherVehicle()
1390 if attacherVehicle2 ~= nil then
1391
1392 local attacherJointIndex = attacherVehicle2:getAttacherJointIndexFromObject(attacherVehicle1)
1393 local implement = attacherVehicle2:getImplementFromAttacherJointIndex(attacherJointIndex)
1394
1395 if implement.inputJointDescIndex == skipNode.inputAttacherJointIndex then
1396 local firstValidTarget, isSkipNode = attacherVehicle2:getConnectionTarget(attacherJointIndex, skipNode.type, skipNode.specType)
1397 if firstValidTarget ~= nil then
1398 local hose = attacherVehicle1:getClonedSkipHoseNode(sourceHose, skipNode)
1399 if not isSkipNode then
1400 attacherVehicle1:connectHose(hose, attacherVehicle2, firstValidTarget)
1401 else
1402 attacherVehicle1:connectHoseToSkipNode(hose, attacherVehicle2, firstValidTarget, sourceHose, attacherVehicle1)
1403 end
1404
1405 if skipNode.parentHose ~= nil then
1406 skipNode.parentVehicle:removeWashableNode(skipNode.parentHose.hoseNode)
1407 delete(skipNode.parentHose.hoseNode)
1408 table.removeElement(spec.updateableHoses, skipNode.parentHose.childHose)
1409 end
1410 skipNode.parentVehicle = attacherVehicle1
1411 skipNode.parentHose = hose
1412
1413 sourceHose.parentVehicle = attacherVehicle1
1414 sourceHose.parentHose = hose
1415
1416 hose.childVehicle = self
1417 hose.childHose = sourceHose
1418
1419 attacherVehicle1:addAllSubWashableNodes(hose.hoseNode)
1420 else
1421 --same hose is still active, just update the relations
1422 if skipNode.parentHose ~= nil then
1423 sourceHose.parentVehicle = skipNode.parentVehicle
1424 sourceHose.parentHose = skipNode.parentHose
1425
1426 sourceHose.parentHose.childVehicle = self
1427 sourceHose.parentHose.childHose = sourceHose
1428 end
1429 end
1430 end
1431 end
1432 end
1433 end
1434
1435 table.insert(spec.updateableHoses, sourceHose)
1436 return true
1437end

disconnectCustomHoseNode

Description
Definition
disconnectCustomHoseNode()
Code
1561function ConnectionHoses:disconnectCustomHoseNode(customHose, customTarget)
1562 setTranslation(customHose.node, unpack(customHose.startTranslation))
1563 setRotation(customHose.node, unpack(customHose.startRotation))
1564
1565 customHose.isActive = false
1566 customTarget.isActive = false
1567
1568 customHose.connectedTarget = nil
1569 customTarget.connectedHose = nil
1570
1571 ObjectChangeUtil.setObjectChanges(customHose.objectChanges, false)
1572 ObjectChangeUtil.setObjectChanges(customTarget.objectChanges, false)
1573end

disconnectHose

Description
Definition
disconnectHose()
Code
1175function ConnectionHoses:disconnectHose(hose)
1176 local spec = self.spec_connectionHoses
1177 local target = hose.targetHose
1178 if target ~= nil then
1179 hose.connectedObject:updateToolConnectionHose(self, hose, hose.connectedObject, target, false)
1180
1181 local hoseHasSkipNodeTarget = target.isSkipNode ~= nil and target.isSkipNode
1182 local hoseIsFromSkipNodeTarget = hose.isClonedSkipNodeHose ~= nil and hose.isClonedSkipNodeHose
1183 if hoseHasSkipNodeTarget or hoseIsFromSkipNodeTarget then
1184 --remove all skip node connections recursively in both directions
1185 if hose.parentVehicle ~= nil and hose.parentHose ~= nil then
1186 hose.parentHose.childVehicle = nil
1187 hose.parentHose.childHose = nil
1188 hose.parentVehicle:disconnectHose(hose.parentHose)
1189 end
1190
1191 if hose.childVehicle ~= nil and hose.childHose ~= nil then
1192 hose.childHose.parentVehicle = nil
1193 hose.childHose.parentHose = nil
1194 hose.childVehicle:disconnectHose(hose.childHose)
1195 end
1196
1197 target.parentHose = nil
1198 end
1199
1200 if target.adapter ~= nil and target.adapter.isLinked ~= nil and target.adapter.isLinked then
1201 hose.connectedObject:removeAllSubWashableNodes(target.adapter.node)
1202 delete(target.adapter.node)
1203
1204 target.adapter.node = target.node
1205 target.adapter.refNode = target.node
1206 target.adapter.isLinked = false
1207 end
1208
1209 setVisibility(hose.visibilityNode, false)
1210 ObjectChangeUtil.setObjectChanges(target.objectChanges, false)
1211 ObjectChangeUtil.setObjectChanges(hose.objectChanges, false)
1212
1213 g_connectionHoseManager:closeSocket(hose.socket)
1214 g_connectionHoseManager:closeSocket(target.socket)
1215
1216 target.connectedObject = nil
1217 hose.connectedObject = nil
1218 hose.targetHose = nil
1219
1220 table.removeElement(spec.updateableHoses, hose)
1221 end
1222end

getCenterPointAngle

Description
Definition
getCenterPointAngle()
Code
431function ConnectionHoses:getCenterPointAngle(node, cX, cY, cZ, eX, eY, eZ, useWorldSpace)
432 local lengthStartToCenter = MathUtil.vector3Length(cX, cY, cZ)
433 local lengthCenterToEnd = math.abs(MathUtil.vector3Length(cX-eX, cY-eY, cZ-eZ))
434
435 local _, sY, _ = getWorldTranslation(node)
436 if useWorldSpace then
437 _, cY, _ = localToWorld(node, cX, cY, cZ)
438 _, eY, _ = localToWorld(node, eX, eY, eZ)
439 else
440 sY = 0
441 end
442
443 local lengthStartToCenter2 = sY-cY
444 local lengthCenterToEnd2 = eY-cY
445
446 local angle1 = math.acos(lengthStartToCenter2/lengthStartToCenter)
447 local angle2 = math.acos(lengthCenterToEnd2/lengthCenterToEnd)
448
449 return angle1, angle2
450end

getCenterPointAngleRegulation

Description
Definition
getCenterPointAngleRegulation()
Code
454function ConnectionHoses:getCenterPointAngleRegulation(node, cX, cY, cZ, eX, eY, eZ, angle1, angle2, targetAngle, useWorldSpace)
455 local sX, sY, sZ = getWorldTranslation(node)
456 if useWorldSpace then
457 local _
458 cX, _, cZ = localToWorld(node, cX, cY, cZ)
459 eX, _, eZ = localToWorld(node, eX, eY, eZ)
460 else
461 sX, sY, sZ = 0, 0, 0
462 end
463
464 local startCenterLength = MathUtil.vector2Length(sX-cX, sZ-cZ)
465 local centerEndLength = MathUtil.vector2Length(eX-cX, eZ-cZ)
466
467 local pct = angle1/(angle1+angle2)
468 local alpha = math.pi * 0.5 - (pct * targetAngle)
469
470 local newY1 = math.tan(alpha) * startCenterLength
471 local newY2 = math.tan(alpha) * centerEndLength
472
473 local newY = (newY1 + newY2) / 2
474
475 if useWorldSpace then
476 return worldToLocal(node, cX, sY-newY, cZ)
477 else
478 return cX, sY-newY, cZ
479 end
480end

getClonedSkipHoseNode

Description
Definition
getClonedSkipHoseNode()
Code
924function ConnectionHoses:getClonedSkipHoseNode(sourceHose, skipNode)
925 local clonedHose = {}
926
927 clonedHose.isClonedSkipNodeHose = true
928
929 clonedHose.type = sourceHose.type
930 clonedHose.specType = sourceHose.specType
931 clonedHose.hoseType = sourceHose.hoseType
932 clonedHose.node = skipNode.node
933
934 clonedHose.component = self:getParentComponent(skipNode.node)
935 clonedHose.lastVelY = 0
936 clonedHose.lastVelZ = 0
937 clonedHose.dampingRange = 0.05
938 clonedHose.dampingFactor = 50
939
940 clonedHose.minDeltaYComponent = self:getParentComponent(skipNode.node)
941 clonedHose.minDeltaY = math.huge
942
943 clonedHose.length = skipNode.length or sourceHose.length
944 clonedHose.diameter = sourceHose.diameter
945 clonedHose.isTwoPointHose = skipNode.isTwoPointHose
946
947 clonedHose.color = sourceHose.color
948
949 local hose, startStraightening, endStraightening, minCenterPointAngle = g_connectionHoseManager:getClonedHoseNode(clonedHose.type, clonedHose.hoseType, clonedHose.length, clonedHose.diameter, clonedHose.color, self.customEnvironment)
950
951 if hose ~= nil then
952 link(clonedHose.node, hose)
953 setTranslation(hose, 0, 0, 0)
954 setRotation(hose, 0, 0, 0)
955
956 clonedHose.hoseNode = hose
957 clonedHose.visibilityNode = hose
958 clonedHose.startStraightening = startStraightening
959 clonedHose.endStraightening = endStraightening
960 clonedHose.endStraighteningBase = endStraightening
961 clonedHose.endStraighteningDirectionBase = {0, 0, 1}
962 clonedHose.endStraighteningDirection = clonedHose.endStraighteningDirectionBase
963 clonedHose.minCenterPointAngle = minCenterPointAngle
964
965 setVisibility(clonedHose.visibilityNode, false)
966 else
967 Logging.xmlWarning(self.xmlFile, "Unable to find connection hose with length '%.2f' and diameter '%.2f' in '%s'", clonedHose.length, clonedHose.diameter, "skipHoseClone")
968 return false
969 end
970
971 clonedHose.objectChanges = {}
972
973 return clonedHose
974end

getConnectionHoseConfigIndex

Description
Definition
getConnectionHoseConfigIndex()
Code
272function ConnectionHoses:getConnectionHoseConfigIndex()
273 return 1
274end

getConnectionHosesByInputAttacherJoint

Description
Definition
getConnectionHosesByInputAttacherJoint()
Code
1098function ConnectionHoses:getConnectionHosesByInputAttacherJoint(inputJointDescIndex)
1099 local spec = self.spec_connectionHoses
1100
1101 if spec.hoseNodesByInputAttacher[inputJointDescIndex] ~= nil then
1102 return spec.hoseNodesByInputAttacher[inputJointDescIndex]
1103 end
1104
1105 return {}
1106end

getConnectionTarget

Description
Definition
getConnectionTarget()
Code
978function ConnectionHoses:getConnectionTarget(attacherJointIndex, type, specType, excludeToolConnections)
979 local spec = self.spec_connectionHoses
980 if #spec.targetNodes == 0 and #spec.hoseSkipNodes == 0 then
981 return nil
982 end
983
984 local nodes = spec.targetNodesByType[type]
985 if nodes ~= nil then
986 for _, node in ipairs(nodes) do
987 if node.attacherJointIndices[attacherJointIndex] ~= nil then
988 if node.specType == specType then
989 if not self:getIsConnectionTargetUsed(node) then
990 local toolConnectionHose = spec.targetNodeToToolConnection[node.index]
991 if toolConnectionHose ~= nil and excludeToolConnections ~= nil and excludeToolConnections then
992 if toolConnectionHose.delayedMounting == nil then
993 return nil
994 end
995 end
996
997 return node, false
998 end
999 end
1000 end
1001 end
1002 end
1003
1004 nodes = spec.hoseSkipNodeByType[type]
1005 if nodes ~= nil then
1006 for _, node in ipairs(nodes) do
1007 if node.specType == specType then
1008 if self:getIsSkipNodeAvailable(node) then
1009 return node, true
1010 end
1011 end
1012 end
1013 end
1014
1015 return nil
1016end

getIsConnectionHoseUsed

Description
Definition
getIsConnectionHoseUsed()
Code
1072function ConnectionHoses:getIsConnectionHoseUsed(desc)
1073 return desc.connectedObject ~= nil
1074end

getIsConnectionTargetUsed

Description
Definition
getIsConnectionTargetUsed()
Code
1066function ConnectionHoses:getIsConnectionTargetUsed(desc)
1067 return desc.connectedObject ~= nil
1068end

getIsSkipNodeAvailable

Description
Definition
getIsSkipNodeAvailable()
Code
1078function ConnectionHoses:getIsSkipNodeAvailable(skipNode)
1079 if self.getAttacherVehicle == nil then
1080 return false
1081 end
1082
1083 local attacherVehicle = self:getAttacherVehicle()
1084 if attacherVehicle ~= nil then
1085 local attacherJointIndex = attacherVehicle:getAttacherJointIndexFromObject(self)
1086 local implement = attacherVehicle:getImplementFromAttacherJointIndex(attacherJointIndex)
1087
1088 if implement.inputJointDescIndex == skipNode.inputAttacherJointIndex then
1089 return attacherVehicle:getConnectionTarget(attacherJointIndex, skipNode.type, skipNode.specType, true) ~= nil and skipNode.parentHose == nil
1090 end
1091 end
1092
1093 return false
1094end

initSpecialization

Description
Definition
initSpecialization()
Code
23function ConnectionHoses.initSpecialization()
24 local schema = Vehicle.xmlSchema
25 schema:setXMLSpecializationType("ConnectionHoses")
26
27 schema:register(XMLValueType.FLOAT, "vehicle.connectionHoses#maxUpdateDistance", "Max. distance to vehicle root to update connection hoses", ConnectionHoses.DEFAULT_MAX_UPDATE_DISTANCE)
28
29 ConnectionHoses.registerConnectionHoseXMLPaths(schema, "vehicle.connectionHoses")
30 ConnectionHoses.registerConnectionHoseXMLPaths(schema, "vehicle.connectionHoses.connectionHoseConfigurations.connectionHoseConfiguration(?)")
31
32 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.connectionHoses.connectionHoseConfigurations.connectionHoseConfiguration(?)")
33
34 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_TOOL_XML_KEY .. ".connectionHoses#customHoseIndices", "Custom hoses to update")
35 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_TOOL_XML_KEY .. ".connectionHoses#customTargetIndices", "Custom hose targets to update")
36 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_PART_XML_KEY .. ".connectionHoses#customHoseIndices", "Custom hoses to update")
37 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_PART_XML_KEY .. ".connectionHoses#customTargetIndices", "Custom hose targets to update")
38
39 schema:setXMLSpecializationType()
40end

iterateConnectionTargets

Description
Definition
iterateConnectionTargets()
Code
1020function ConnectionHoses:iterateConnectionTargets(func, attacherJointIndex, type, specType, excludeToolConnections)
1021 local spec = self.spec_connectionHoses
1022 if #spec.targetNodes == 0 and #spec.hoseSkipNodes == 0 then
1023 return nil
1024 end
1025
1026 local nodes = spec.targetNodesByType[type]
1027 if nodes ~= nil then
1028 for _, node in ipairs(nodes) do
1029 if node.attacherJointIndices[attacherJointIndex] ~= nil then
1030 if node.specType == specType then
1031 if not self:getIsConnectionTargetUsed(node) then
1032 local toolConnectionHose = spec.targetNodeToToolConnection[node.index]
1033 if toolConnectionHose ~= nil and excludeToolConnections ~= nil and excludeToolConnections then
1034 if toolConnectionHose.delayedMounting == nil then
1035 return nil
1036 end
1037 end
1038
1039 if not func(node, false) then
1040 break
1041 end
1042 end
1043 end
1044 end
1045 end
1046 end
1047
1048 nodes = spec.hoseSkipNodeByType[type]
1049 if nodes ~= nil then
1050 for _, node in ipairs(nodes) do
1051 if node.specType == specType then
1052 if self:getIsSkipNodeAvailable(node) then
1053 if not func(node, true) then
1054 break
1055 end
1056 end
1057 end
1058 end
1059 end
1060
1061 return nil
1062end

loadConnectionHosesFromXML

Description
Definition
loadConnectionHosesFromXML()
Code
484function ConnectionHoses:loadConnectionHosesFromXML(xmlFile, key)
485 local spec = self.spec_connectionHoses
486
487 xmlFile:iterate(key .. ".skipNode", function(_, hoseKey)
488 local entry = {}
489 if self:loadHoseSkipNode(xmlFile, hoseKey, entry) then
490 table.insert(spec.hoseSkipNodes, entry)
491
492 if spec.hoseSkipNodeByType[entry.type] == nil then
493 spec.hoseSkipNodeByType[entry.type] = {}
494 end
495
496 table.insert(spec.hoseSkipNodeByType[entry.type], entry)
497 end
498 end)
499
500 self:addHoseTargetNodes(xmlFile, key .. ".target")
501
502 xmlFile:iterate(key .. ".toolConnectorHose", function(_, hoseKey)
503 local entry = {}
504 if self:loadToolConnectorHoseNode(xmlFile, hoseKey, entry) then
505 table.insert(spec.toolConnectorHoses, entry)
506
507 spec.targetNodeToToolConnection[entry.startTargetNodeIndex] = entry
508 spec.targetNodeToToolConnection[entry.endTargetNodeIndex] = entry
509 end
510 end)
511
512 xmlFile:iterate(key .. ".hose", function(_, hoseKey)
513 local entry = {}
514 if self:loadHoseNode(xmlFile, hoseKey, entry, true) then
515 table.insert(spec.hoseNodes, entry)
516 entry.index = #spec.hoseNodes
517
518 for _, index in pairs(entry.inputAttacherJointIndices) do
519 if spec.hoseNodesByInputAttacher[index] == nil then
520 spec.hoseNodesByInputAttacher[index] = {}
521 end
522
523 table.insert(spec.hoseNodesByInputAttacher[index], entry)
524 end
525 end
526 end)
527
528 xmlFile:iterate(key .. ".localHose", function(_, hoseKey)
529 local hose = {}
530 if self:loadHoseNode(xmlFile, hoseKey..".hose", hose, false) then
531
532 local target = {}
533 if self:loadHoseTargetNode(xmlFile, hoseKey..".target", target) then
534 table.insert(spec.localHoseNodes, {hose=hose, target=target})
535 end
536 end
537 end)
538
539 self:loadCustomHosesFromXML(spec.customHoses, spec.customHosesByAttacher, spec.customHosesByInputAttacher, xmlFile, key .. ".customHose")
540
541 self:loadCustomHosesFromXML(spec.customHoseTargets, spec.customHoseTargetsByAttacher, spec.customHoseTargetsByInputAttacher, xmlFile, key .. ".customTarget")
542end

loadCustomHosesFromXML

Description
Definition
loadCustomHosesFromXML()
Code
666function ConnectionHoses:loadCustomHosesFromXML(targetTable, attacherJointMapping, inputAttacherJointMapping, xmlFile, key)
667 xmlFile:iterate(key, function(_, customKey)
668 local entry = {}
669 entry.node = xmlFile:getValue(customKey .. "#node", nil, self.components, self.i3dMappings)
670 if entry.node ~= nil then
671 entry.type = xmlFile:getValue(customKey .. "#type")
672 if entry.type ~= nil then
673 entry.type = entry.type:upper()
674
675 local attacherJointIndices = xmlFile:getValue(customKey .. "#attacherJointIndices", nil, true)
676 entry.attacherJointIndices = {}
677 for _, v in ipairs(attacherJointIndices) do
678 entry.attacherJointIndices[v] = v
679
680 if attacherJointMapping[v] == nil then
681 attacherJointMapping[v] = {}
682 end
683
684 table.insert(attacherJointMapping[v], entry)
685 end
686
687 local inputAttacherJointIndices = xmlFile:getValue(customKey .. "#inputAttacherJointIndices", nil, true)
688 entry.inputAttacherJointIndices = {}
689 for _, v in ipairs(inputAttacherJointIndices) do
690 entry.inputAttacherJointIndices[v] = v
691
692 if inputAttacherJointMapping[v] == nil then
693 inputAttacherJointMapping[v] = {}
694 end
695
696 table.insert(inputAttacherJointMapping[v], entry)
697 end
698
699 entry.objectChanges = {}
700 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, customKey, entry.objectChanges, self.components, self)
701 ObjectChangeUtil.setObjectChanges(entry.objectChanges, false)
702
703 entry.startTranslation = {getTranslation(entry.node)}
704 entry.startRotation = {getRotation(entry.node)}
705
706 entry.isActive = false
707
708 table.insert(targetTable, entry)
709 else
710 Logging.xmlWarning(xmlFile, "Missing type for custom hose '%s'", customKey)
711 end
712 else
713 Logging.xmlWarning(xmlFile, "Missing node for custom hose '%s'", customKey)
714 end
715 end)
716end

loadExtraDependentParts

Description
Definition
loadExtraDependentParts()
Code
1577function ConnectionHoses:loadExtraDependentParts(superFunc, xmlFile, baseName, entry)
1578 if not superFunc(self, xmlFile, baseName, entry) then
1579 return false
1580 end
1581
1582 local customHoseIndices = xmlFile:getValue(baseName.. ".connectionHoses#customHoseIndices", nil, true)
1583 if #customHoseIndices > 0 then
1584 entry.customHoseIndices = customHoseIndices
1585 end
1586
1587 local customTargetIndices = xmlFile:getValue(baseName.. ".connectionHoses#customTargetIndices", nil, true)
1588 if #customTargetIndices > 0 then
1589 entry.customTargetIndices = customTargetIndices
1590 end
1591
1592 return true
1593end

loadHoseNode

Description
Definition
loadHoseNode()
Code
778function ConnectionHoses:loadHoseNode(xmlFile, hoseKey, entry, isBaseHose)
779 entry.inputAttacherJointIndices = {}
780
781 local inputAttacherJointIndices = xmlFile:getValue(hoseKey .. "#inputAttacherJointIndices", nil, true)
782 for _, inputAttacherJointIndex in ipairs(inputAttacherJointIndices) do
783 entry.inputAttacherJointIndices[inputAttacherJointIndex] = inputAttacherJointIndex
784 end
785
786 local inputAttacherJointNodes = xmlFile:getValue(hoseKey .. "#inputAttacherJointNodes", nil, self.components, self.i3dMappings, true)
787 for _, node in ipairs(inputAttacherJointNodes) do
788 local inputAttacherJointIndex = self:getInputAttacherJointIndexByNode(node)
789 if inputAttacherJointIndex ~= nil then
790 entry.inputAttacherJointIndices[inputAttacherJointIndex] = inputAttacherJointIndex
791 end
792 end
793
794 entry.type = xmlFile:getValue(hoseKey .. "#type")
795 entry.specType = xmlFile:getValue(hoseKey .. "#specType")
796 if entry.type == nil then
797 Logging.xmlWarning(xmlFile, "Missing type attribute in '%s'", hoseKey)
798 return false
799 end
800
801 entry.hoseType = xmlFile:getValue(hoseKey .. "#hoseType", "DEFAULT")
802 entry.node = xmlFile:getValue(hoseKey .. "#node", nil, self.components, self.i3dMappings)
803 if entry.node == nil then
804 Logging.xmlWarning(xmlFile, "Missing node for connection hose '%s'", hoseKey)
805 return false
806 end
807
808 if isBaseHose then
809 local spec = self.spec_connectionHoses
810 local type = entry.type .. (entry.specType or "")
811 if spec.numHosesByType[type] == nil then
812 spec.numHosesByType[type] = 0
813 end
814 spec.numHosesByType[type] = spec.numHosesByType[type] + 1
815 entry.typedIndex = spec.numHosesByType[type]
816 end
817
818 entry.isTwoPointHose = xmlFile:getValue(hoseKey .. "#isTwoPointHose", false)
819 entry.isWorldSpaceHose = xmlFile:getValue(hoseKey .. "#isWorldSpaceHose", true)
820
821 entry.component = self:getParentComponent(entry.node)
822 entry.lastVelY = 0
823 entry.lastVelZ = 0
824 entry.dampingRange = xmlFile:getValue(hoseKey .. "#dampingRange", 0.05)
825 entry.dampingFactor = xmlFile:getValue(hoseKey .. "#dampingFactor", 50)
826
827 entry.length = xmlFile:getValue(hoseKey .. "#length", 3)
828 entry.diameter = xmlFile:getValue(hoseKey .. "#diameter", 0.02)
829 entry.straighteningFactor = xmlFile:getValue(hoseKey .. "#straighteningFactor", 1)
830 entry.minCenterPointAngle = xmlFile:getValue(hoseKey .. "#minCenterPointAngle")
831
832 entry.minCenterPointOffset = xmlFile:getValue(hoseKey .. "#minCenterPointOffset", nil, true)
833 entry.maxCenterPointOffset = xmlFile:getValue(hoseKey .. "#maxCenterPointOffset", nil, true)
834
835 if entry.minCenterPointOffset ~= nil and entry.maxCenterPointOffset ~= nil then
836 for i=1, 3 do
837 if entry.minCenterPointOffset[i] == 0 then
838 entry.minCenterPointOffset[i] = -math.huge
839 end
840
841 if entry.maxCenterPointOffset[i] == 0 then
842 entry.maxCenterPointOffset[i] = math.huge
843 end
844 end
845 end
846
847 entry.minDeltaY = xmlFile:getValue(hoseKey .. "#minDeltaY", math.huge)
848 entry.minDeltaYComponent = xmlFile:getValue(hoseKey .. "#minDeltaYComponent", entry.component, self.components, self.i3dMappings)
849
850 entry.color = xmlFile:getValue(hoseKey.."#color", nil, true)
851
852 entry.adapterName = xmlFile:getValue(hoseKey .. "#adapterType")
853 entry.outgoingAdapter = xmlFile:getValue(hoseKey .. "#outgoingAdapter")
854
855 entry.adapterNode = xmlFile:getValue(hoseKey .. "#adapterNode", nil, self.components, self.i3dMappings)
856 if entry.adapterNode ~= nil then
857 local node = g_connectionHoseManager:getClonedAdapterNode(entry.type, entry.adapterName or "DEFAULT", self.customEnvironment, true)
858 if node ~= nil then
859 link(entry.adapterNode, node)
860 else
861 Logging.xmlWarning(xmlFile, "Unable to find detached adapter for type '%s' in '%s'", entry.adapterName or "DEFAULT", hoseKey)
862 end
863 end
864
865 local socketName = xmlFile:getValue(hoseKey .. "#socket")
866 if socketName ~= nil then
867 local socketColor = xmlFile:getValue(hoseKey .. "#socketColor", nil, true)
868 entry.socket = g_connectionHoseManager:linkSocketToNode(socketName, entry.node, self.customEnvironment, socketColor)
869 if entry.socket ~= nil then
870 setRotation(entry.socket.node, 0, math.pi, 0)
871 end
872 end
873
874 local hose, startStraightening, endStraightening, minCenterPointAngle = g_connectionHoseManager:getClonedHoseNode(entry.type, entry.hoseType, entry.length, entry.diameter, entry.color, self.customEnvironment)
875
876 if hose ~= nil then
877 local outgoingNode, visibilityNode = g_connectionHoseManager:getSocketTarget(entry.socket, entry.node), hose
878 local rx, ry, rz = 0, 0, 0
879 if entry.outgoingAdapter ~= nil then
880 local node, referenceNode = g_connectionHoseManager:getClonedAdapterNode(entry.type, entry.outgoingAdapter, self.customEnvironment)
881 if node ~= nil then
882 link(outgoingNode, node)
883 outgoingNode = referenceNode
884 visibilityNode = node
885 ry = math.pi
886
887 if entry.socket == nil then
888 setRotation(node, 0, ry, 0)
889 end
890 else
891 Logging.xmlWarning(xmlFile, "Unable to find adapter type '%s' in '%s'", entry.outgoingAdapter, hoseKey)
892 end
893 end
894
895 link(outgoingNode, hose)
896 setTranslation(hose, 0, 0, 0)
897 setRotation(hose, rx, ry, rz)
898
899 entry.hoseNode = hose
900 entry.visibilityNode = visibilityNode
901 entry.startStraightening = startStraightening * entry.straighteningFactor
902 entry.endStraightening = endStraightening
903 entry.endStraighteningBase = endStraightening
904 entry.endStraighteningDirectionBase = {0, 0, 1}
905 entry.endStraighteningDirection = entry.endStraighteningDirectionBase
906 entry.minCenterPointAngle = entry.minCenterPointAngle or minCenterPointAngle
907
908 setVisibility(entry.visibilityNode, false)
909 else
910 Logging.xmlWarning(xmlFile, "Unable to find connection hose with length '%.2f' and diameter '%.2f' in '%s'", entry.length, entry.diameter, hoseKey)
911 return false
912 end
913
914 entry.objectChanges = {}
915 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, hoseKey, entry.objectChanges, self.components, self)
916 ObjectChangeUtil.setObjectChanges(entry.objectChanges, false)
917
918 return true
919end

loadHoseSkipNode

Description
Definition
loadHoseSkipNode()
Code
546function ConnectionHoses:loadHoseSkipNode(xmlFile, targetKey, entry)
547 entry.node = xmlFile:getValue(targetKey .. "#node", nil, self.components, self.i3dMappings)
548
549 if entry.node == nil then
550 Logging.xmlWarning(xmlFile, "Missing node for hose skip node '%s'", targetKey)
551 return false
552 end
553
554 entry.inputAttacherJointIndex = xmlFile:getValue(targetKey .. "#inputAttacherJointIndex", 1)
555 entry.attacherJointIndex = xmlFile:getValue(targetKey .. "#attacherJointIndex", 1)
556
557 entry.type = xmlFile:getValue(targetKey .. "#type")
558 entry.specType = xmlFile:getValue(targetKey .. "#specType")
559
560 if entry.type == nil then
561 Logging.xmlWarning(xmlFile, "Missing type for hose skip node '%s'", targetKey)
562 return false
563 end
564
565 entry.length = xmlFile:getValue(targetKey .. "#length")
566 entry.isTwoPointHose = xmlFile:getValue(targetKey .. "#isTwoPointHose", false)
567
568 entry.isSkipNode = true
569
570 return true
571end

loadHoseTargetNode

Description
Definition
loadHoseTargetNode()
Code
720function ConnectionHoses:loadHoseTargetNode(xmlFile, targetKey, entry)
721 entry.node = xmlFile:getValue(targetKey .. "#node", nil, self.components, self.i3dMappings)
722
723 if entry.node == nil then
724 Logging.xmlWarning(xmlFile, "Missing node for connection hose target '%s'", targetKey)
725 return false
726 end
727
728 entry.attacherJointIndices = {}
729
730 local attacherJointIndices = xmlFile:getValue(targetKey .. "#attacherJointIndices", nil, true)
731 for _, attacherJointIndex in ipairs(attacherJointIndices) do
732 entry.attacherJointIndices[attacherJointIndex] = attacherJointIndex
733 end
734
735 local attacherJointNodes = xmlFile:getValue(targetKey .. "#attacherJointNodes", nil, self.components, self.i3dMappings, true)
736 for _, node in ipairs(attacherJointNodes) do
737 local attacherJointIndex = self:getAttacherJointIndexByNode(node)
738 if attacherJointIndex ~= nil then
739 entry.attacherJointIndices[attacherJointIndex] = attacherJointIndex
740 end
741 end
742
743 entry.type = xmlFile:getValue(targetKey .. "#type")
744 entry.specType = xmlFile:getValue(targetKey .. "#specType")
745 entry.straighteningFactor = xmlFile:getValue(targetKey .. "#straighteningFactor", 1)
746 entry.straighteningDirection = xmlFile:getValue(targetKey .. "#straighteningDirection", nil, true)
747
748 local socketName = xmlFile:getValue(targetKey .. "#socket")
749 if socketName ~= nil then
750 local socketColor = xmlFile:getValue(targetKey .. "#socketColor", nil, true)
751 entry.socket = g_connectionHoseManager:linkSocketToNode(socketName, entry.node, self.customEnvironment, socketColor)
752 end
753
754 if entry.type ~= nil then
755 entry.adapterName = xmlFile:getValue(targetKey .. "#adapterType", "DEFAULT")
756
757 -- empty adapter with target node as reference
758 -- will be replaced with the real adapter on connecting
759 if entry.adapter == nil then
760 entry.adapter = {}
761 entry.adapter.node = entry.node
762 entry.adapter.refNode = entry.node
763 end
764
765 entry.objectChanges = {}
766 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, targetKey, entry.objectChanges, self.components, self)
767 ObjectChangeUtil.setObjectChanges(entry.objectChanges, false)
768 else
769 Logging.xmlWarning(xmlFile, "Missing type for '%s'", targetKey)
770 return false
771 end
772
773 return true
774end

loadToolConnectorHoseNode

Description
Definition
loadToolConnectorHoseNode()
Code
575function ConnectionHoses:loadToolConnectorHoseNode(xmlFile, targetKey, entry)
576 local spec = self.spec_connectionHoses
577
578 local key = string.format("%s.startTarget", targetKey)
579 entry.startTargetNodeIndex = self:addHoseTargetNodes(xmlFile, key)
580
581 if entry.startTargetNodeIndex == nil then
582 Logging.xmlWarning(xmlFile, "startTarget is missing for tool connection hose '%s'", targetKey)
583 return false
584 end
585
586 key = string.format("%s.endTarget", targetKey)
587 entry.endTargetNodeIndex = self:addHoseTargetNodes(xmlFile, key)
588
589 if entry.endTargetNodeIndex == nil then
590 Logging.xmlWarning(xmlFile, "endTarget is missing for tool connection hose '%s'", targetKey)
591 return false
592 end
593
594 local startTarget = spec.targetNodes[entry.startTargetNodeIndex]
595 local endTarget = spec.targetNodes[entry.endTargetNodeIndex]
596
597 for index, _ in pairs(startTarget.attacherJointIndices) do
598 if endTarget.attacherJointIndices[index] ~= nil then
599 Logging.xmlWarning(xmlFile, "Double usage of attacher joint index '%d' in '%s'", index, targetKey)
600 end
601 end
602
603 entry.moveNodes = xmlFile:getValue(targetKey .. "#moveNodes", true)
604 entry.additionalHose = xmlFile:getValue(targetKey .. "#additionalHose", true)
605
606 -- make sure the two nodes are pointing towards each other
607 if entry.moveNodes then
608 local x1, y1, z1 = getTranslation(startTarget.node)
609 local x2, y2, z2 = getTranslation(endTarget.node)
610 local dirX, dirY, dirZ = MathUtil.vector3Normalize(x1-x2, y1-y2, z1-z2)
611 local upX, upY, upZ = localDirectionToLocal(endTarget.node, getParent(endTarget.node), 0, 1, 0)
612 if (dirX ~= 0 or dirY ~= 0 or dirZ ~= 0)
613 and not MathUtil.isNan(dirX) and not MathUtil.isNan(dirY) and not MathUtil.isNan(dirZ) then
614 setDirection(startTarget.node, -dirX, -dirY, -dirZ, upX, upY, upZ)
615 setDirection(endTarget.node, dirX, dirY, dirZ, upX, upY, upZ)
616 end
617 end
618
619 entry.mountingNode = xmlFile:getValue(targetKey .. "#mountingNode", nil, self.components, self.i3dMappings)
620
621 if entry.mountingNode ~= nil then
622 setVisibility(entry.mountingNode, false)
623 end
624
625 local type = spec.targetNodes[entry.startTargetNodeIndex].type .. (spec.targetNodes[entry.startTargetNodeIndex].specType or "")
626 if spec.numToolConnectionsByType[type] == nil then
627 spec.numToolConnectionsByType[type] = 0
628 end
629 spec.numToolConnectionsByType[type] = spec.numToolConnectionsByType[type] + 1
630 entry.typedIndex = spec.numToolConnectionsByType[type]
631
632 entry.connected = false
633
634 return true
635end

onLoad

Description
Definition
onLoad()
Code
190function ConnectionHoses:onLoad(savegame)
191 local spec = self.spec_connectionHoses
192
193 local configKey = string.format("vehicle.connectionHoses.connectionHoseConfigurations.connectionHoseConfiguration(%d)", spec.configIndex - 1)
194 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.connectionHoses.connectionHoseConfigurations.connectionHoseConfiguration", spec.configIndex, self.components, self)
195
196 spec.numHosesByType = {}
197 spec.numToolConnectionsByType = {}
198
199 spec.hoseSkipNodes = {}
200 spec.hoseSkipNodeByType = {}
201
202 spec.targetNodes = {}
203 spec.targetNodesByType = {}
204
205 spec.toolConnectorHoses = {}
206 spec.targetNodeToToolConnection = {}
207
208 spec.hoseNodes = {}
209 spec.hoseNodesByInputAttacher = {}
210
211 spec.localHoseNodes = {}
212
213 spec.customHoses = {}
214 spec.customHosesByAttacher = {}
215 spec.customHosesByInputAttacher = {}
216
217 spec.customHoseTargets = {}
218 spec.customHoseTargetsByAttacher = {}
219 spec.customHoseTargetsByInputAttacher = {}
220
221 self:loadConnectionHosesFromXML(self.xmlFile, "vehicle.connectionHoses")
222
223 if self.xmlFile:hasProperty(configKey) then
224 self:loadConnectionHosesFromXML(self.xmlFile, configKey)
225 end
226
227 spec.maxUpdateDistance = self.xmlFile:getValue("vehicle.connectionHoses#maxUpdateDistance", ConnectionHoses.DEFAULT_MAX_UPDATE_DISTANCE)
228
229 spec.targetNodesAvailable = #spec.targetNodes > 0
230 spec.hoseNodesAvailable = #spec.hoseNodes > 0
231 spec.localHosesAvailable = #spec.localHoseNodes > 0
232 spec.skipNodesAvailable = #spec.hoseSkipNodes > 0
233
234 spec.updateableHoses = {}
235
236 -- connection local hoses
237 for _, localHoseNode in ipairs(spec.localHoseNodes) do
238 self:connectHose(localHoseNode.hose, self, localHoseNode.target, false)
239 end
240
241 if not self.isClient or (not spec.targetNodesAvailable and not spec.hoseNodesAvailable and not spec.localHosesAvailable and not spec.skipNodesAvailable) then
242 SpecializationUtil.removeEventListener(self, "onPostUpdate", ConnectionHoses)
243 end
244end

onPostAttach

Description
Definition
onPostAttach()
Code
1625function ConnectionHoses:onPostAttach(attacherVehicle, inputJointDescIndex, jointDescIndex)
1626 self:connectHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex)
1627 self:connectCustomHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex)
1628end

onPostUpdate

Description
Definition
onPostUpdate()
Code
248function ConnectionHoses:onPostUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
249 local spec = self.spec_connectionHoses
250 if self.currentUpdateDistance < spec.maxUpdateDistance then
251 for i=1, #spec.updateableHoses do
252 local hose = spec.updateableHoses[i]
253 if self.updateLoopIndex == hose.connectedObject.updateLoopIndex then
254 self:updateConnectionHose(hose, i)
255 end
256 end
257
258 if self.getAttachedImplements ~= nil then
259 local impements = self:getAttachedImplements()
260 for i=1, #impements do
261 local object = impements[i].object
262 if object.updateAttachedConnectionHoses ~= nil then
263 object:updateAttachedConnectionHoses(self)
264 end
265 end
266 end
267 end
268end

onPreDetach

Description
Definition
onPreDetach()
Code
1632function ConnectionHoses:onPreDetach(attacherVehicle, implement)
1633 local spec = self.spec_connectionHoses
1634
1635 local inputJointDescIndex = self:getActiveInputAttacherJointDescIndex()
1636
1637 local hoses = self:getConnectionHosesByInputAttacherJoint(inputJointDescIndex)
1638 for _, hose in ipairs(hoses) do
1639 self:disconnectHose(hose)
1640 end
1641
1642 for i=#spec.updateableHoses, 1, -1 do
1643 local hose = spec.updateableHoses[i]
1644 if hose.connectedObject == attacherVehicle then
1645 self:disconnectHose(hose)
1646 end
1647 end
1648
1649 -- remove delayed mounting if we detach the implement
1650 local attacherVehicleSpec = attacherVehicle.spec_connectionHoses
1651 if attacherVehicleSpec ~= nil then
1652 for _, toolConnector in pairs(attacherVehicleSpec.toolConnectorHoses) do
1653 if toolConnector.delayedMounting ~= nil then
1654 if toolConnector.delayedMounting.sourceObject == self then
1655 toolConnector.delayedMounting = nil
1656 end
1657 end
1658 end
1659 end
1660
1661 local customHoses = spec.customHosesByInputAttacher[inputJointDescIndex]
1662 if customHoses ~= nil then
1663 for i=1, #customHoses do
1664 local customHose = customHoses[i]
1665 if customHose.isActive then
1666 self:disconnectCustomHoseNode(customHose, customHose.connectedTarget)
1667 end
1668 end
1669 end
1670
1671 local customTargets = spec.customHoseTargetsByInputAttacher[inputJointDescIndex]
1672 if customTargets ~= nil then
1673 for i=1, #customTargets do
1674 local customTarget = customTargets[i]
1675 if customTarget.isActive then
1676 self:disconnectCustomHoseNode(customTarget.connectedHose, customTarget)
1677 end
1678 end
1679 end
1680end

onPreLoad

Description
Definition
onPreLoad()
Code
183function ConnectionHoses:onPreLoad(savegame)
184 local spec = self.spec_connectionHoses
185 spec.configIndex = self:getConnectionHoseConfigIndex()
186end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
17function ConnectionHoses.prerequisitesPresent(specializations)
18 return true
19end

registerConnectionHoseXMLPaths

Description
Definition
registerConnectionHoseXMLPaths()
Code
44function ConnectionHoses.registerConnectionHoseXMLPaths(schema, basePath)
45 schema:register(XMLValueType.NODE_INDEX, basePath .. ".skipNode(?)#node", "Skip node")
46 schema:register(XMLValueType.INT, basePath .. ".skipNode(?)#inputAttacherJointIndex", "Input attacher joint index", 1)
47 schema:register(XMLValueType.INT, basePath .. ".skipNode(?)#attacherJointIndex", "Attacher joint index", 1)
48 schema:register(XMLValueType.STRING, basePath .. ".skipNode(?)#type", "Connection hose type")
49 schema:register(XMLValueType.STRING, basePath .. ".skipNode(?)#specType", "Connection hose specialization type (if defined it needs to match the type of the other tool)")
50 schema:register(XMLValueType.FLOAT, basePath .. ".skipNode(?)#length", "Hose length")
51 schema:register(XMLValueType.BOOL, basePath .. ".skipNode(?)#isTwoPointHose", "Is two point hose without sagging", false)
52
53 ConnectionHoses.registerHoseTargetNodesXMLPaths(schema, basePath .. ".target(?)")
54
55 schema:register(XMLValueType.NODE_INDEX, basePath .. ".toolConnectorHose(?)#mountingNode", "Mounting node to toggle visibility")
56 schema:register(XMLValueType.BOOL, basePath .. ".toolConnectorHose(?)#moveNodes", "Defines if the start and end nodes are moved up depending on hose diameter", true)
57 schema:register(XMLValueType.BOOL, basePath .. ".toolConnectorHose(?)#additionalHose", "Defines if between start and end node a additional hose is created", true)
58 ConnectionHoses.registerHoseTargetNodesXMLPaths(schema, basePath .. ".toolConnectorHose(?).startTarget(?)")
59 ConnectionHoses.registerHoseTargetNodesXMLPaths(schema, basePath .. ".toolConnectorHose(?).endTarget(?)")
60
61 ConnectionHoses.registerHoseNodesXMLPaths(schema, basePath .. ".hose(?)")
62
63 ConnectionHoses.registerHoseNodesXMLPaths(schema, basePath .. ".localHose(?).hose")
64 ConnectionHoses.registerHoseTargetNodesXMLPaths(schema, basePath .. ".localHose(?).target")
65
66 ConnectionHoses.registerCustomHoseNodesXMLPaths(schema, basePath .. ".customHose(?)")
67 ConnectionHoses.registerCustomHoseNodesXMLPaths(schema, basePath .. ".customTarget(?)")
68end

registerCustomHoseNodesXMLPaths

Description
Definition
registerCustomHoseNodesXMLPaths()
Code
120function ConnectionHoses.registerCustomHoseNodesXMLPaths(schema, basePath)
121 schema:register(XMLValueType.NODE_INDEX, basePath .. "#node", "Target or source node")
122 schema:register(XMLValueType.STRING, basePath .. "#type", "Hose type which can be any string that needs to match between hose and target node")
123 schema:register(XMLValueType.VECTOR_N, basePath .. "#attacherJointIndices", "Attacher joint indices")
124 schema:register(XMLValueType.VECTOR_N, basePath .. "#inputAttacherJointIndices", "Input attacher joint indices")
125
126 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
127end

registerEventListeners

Description
Definition
registerEventListeners()
Code
173function ConnectionHoses.registerEventListeners(vehicleType)
174 SpecializationUtil.registerEventListener(vehicleType, "onPreLoad", ConnectionHoses)
175 SpecializationUtil.registerEventListener(vehicleType, "onLoad", ConnectionHoses)
176 SpecializationUtil.registerEventListener(vehicleType, "onPostUpdate", ConnectionHoses)
177 SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", ConnectionHoses)
178 SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", ConnectionHoses)
179end

registerFunctions

Description
Definition
registerFunctions()
Code
131function ConnectionHoses.registerFunctions(vehicleType)
132 SpecializationUtil.registerFunction(vehicleType, "getConnectionHoseConfigIndex", ConnectionHoses.getConnectionHoseConfigIndex)
133 SpecializationUtil.registerFunction(vehicleType, "updateAttachedConnectionHoses", ConnectionHoses.updateAttachedConnectionHoses)
134 SpecializationUtil.registerFunction(vehicleType, "updateConnectionHose", ConnectionHoses.updateConnectionHose)
135 SpecializationUtil.registerFunction(vehicleType, "getCenterPointAngle", ConnectionHoses.getCenterPointAngle)
136 SpecializationUtil.registerFunction(vehicleType, "getCenterPointAngleRegulation", ConnectionHoses.getCenterPointAngleRegulation)
137 SpecializationUtil.registerFunction(vehicleType, "loadConnectionHosesFromXML", ConnectionHoses.loadConnectionHosesFromXML)
138 SpecializationUtil.registerFunction(vehicleType, "loadHoseSkipNode", ConnectionHoses.loadHoseSkipNode)
139 SpecializationUtil.registerFunction(vehicleType, "loadToolConnectorHoseNode", ConnectionHoses.loadToolConnectorHoseNode)
140 SpecializationUtil.registerFunction(vehicleType, "addHoseTargetNodes", ConnectionHoses.addHoseTargetNodes)
141 SpecializationUtil.registerFunction(vehicleType, "loadCustomHosesFromXML", ConnectionHoses.loadCustomHosesFromXML)
142 SpecializationUtil.registerFunction(vehicleType, "loadHoseTargetNode", ConnectionHoses.loadHoseTargetNode)
143 SpecializationUtil.registerFunction(vehicleType, "loadHoseNode", ConnectionHoses.loadHoseNode)
144 SpecializationUtil.registerFunction(vehicleType, "getClonedSkipHoseNode", ConnectionHoses.getClonedSkipHoseNode)
145 SpecializationUtil.registerFunction(vehicleType, "getConnectionTarget", ConnectionHoses.getConnectionTarget)
146 SpecializationUtil.registerFunction(vehicleType, "iterateConnectionTargets", ConnectionHoses.iterateConnectionTargets)
147 SpecializationUtil.registerFunction(vehicleType, "getIsConnectionTargetUsed", ConnectionHoses.getIsConnectionTargetUsed)
148 SpecializationUtil.registerFunction(vehicleType, "getIsConnectionHoseUsed", ConnectionHoses.getIsConnectionHoseUsed)
149 SpecializationUtil.registerFunction(vehicleType, "getIsSkipNodeAvailable", ConnectionHoses.getIsSkipNodeAvailable)
150 SpecializationUtil.registerFunction(vehicleType, "getConnectionHosesByInputAttacherJoint", ConnectionHoses.getConnectionHosesByInputAttacherJoint)
151 SpecializationUtil.registerFunction(vehicleType, "connectHose", ConnectionHoses.connectHose)
152 SpecializationUtil.registerFunction(vehicleType, "disconnectHose", ConnectionHoses.disconnectHose)
153 SpecializationUtil.registerFunction(vehicleType, "updateToolConnectionHose", ConnectionHoses.updateToolConnectionHose)
154 SpecializationUtil.registerFunction(vehicleType, "addHoseToDelayedMountings", ConnectionHoses.addHoseToDelayedMountings)
155 SpecializationUtil.registerFunction(vehicleType, "connectHoseToSkipNode", ConnectionHoses.connectHoseToSkipNode)
156 SpecializationUtil.registerFunction(vehicleType, "connectHosesToAttacherVehicle", ConnectionHoses.connectHosesToAttacherVehicle)
157 SpecializationUtil.registerFunction(vehicleType, "retryHoseSkipNodeConnections", ConnectionHoses.retryHoseSkipNodeConnections)
158 SpecializationUtil.registerFunction(vehicleType, "connectCustomHosesToAttacherVehicle", ConnectionHoses.connectCustomHosesToAttacherVehicle)
159 SpecializationUtil.registerFunction(vehicleType, "connectCustomHoseNode", ConnectionHoses.connectCustomHoseNode)
160 SpecializationUtil.registerFunction(vehicleType, "updateCustomHoseNode", ConnectionHoses.updateCustomHoseNode)
161 SpecializationUtil.registerFunction(vehicleType, "disconnectCustomHoseNode", ConnectionHoses.disconnectCustomHoseNode)
162end

registerHoseNodesXMLPaths

Description
Definition
registerHoseNodesXMLPaths()
Code
89function ConnectionHoses.registerHoseNodesXMLPaths(schema, basePath)
90 schema:register(XMLValueType.VECTOR_N, basePath .. "#inputAttacherJointIndices", "List of corresponding input attacher joint indices")
91 schema:register(XMLValueType.NODE_INDICES, basePath .. "#inputAttacherJointNodes", "List of corresponding input attacher joint nodes (i3dIdentifiers or paths separated by space)")
92 schema:register(XMLValueType.STRING, basePath .. "#type", "Hose type")
93 schema:register(XMLValueType.STRING, basePath .. "#specType", "Connection hose specialization type (if defined it needs to match the type of the other tool)")
94 schema:register(XMLValueType.STRING, basePath .. "#hoseType", "Hose material type", "DEFAULT")
95 schema:register(XMLValueType.NODE_INDEX, basePath .. "#node", "Hose output node")
96 schema:register(XMLValueType.BOOL, basePath .. "#isTwoPointHose", "Is two point hose without sagging", false)
97 schema:register(XMLValueType.BOOL, basePath .. "#isWorldSpaceHose", "Sagging is calculated in world space or local space of hose node", true)
98 schema:register(XMLValueType.STRING, basePath .. "#dampingRange", "Damping range in meters", 0.05)
99 schema:register(XMLValueType.FLOAT, basePath .. "#dampingFactor", "Damping factor", 50)
100 schema:register(XMLValueType.FLOAT, basePath .. "#length", "Hose length", 3)
101 schema:register(XMLValueType.FLOAT, basePath .. "#diameter", "Hose diameter", 0.02)
102 schema:register(XMLValueType.FLOAT, basePath .. "#straighteningFactor", "Straightening Factor", 1)
103 schema:register(XMLValueType.ANGLE, basePath .. "#minCenterPointAngle", "Min. angle of sagged curve", "Defined on connectionHose xml, default 90 degree")
104 schema:register(XMLValueType.VECTOR_TRANS, basePath .. "#minCenterPointOffset", "Min. center point offset from hose node", "unlimited")
105 schema:register(XMLValueType.VECTOR_TRANS, basePath .. "#maxCenterPointOffset", "Max. center point offset from hose node", "unlimited")
106 schema:register(XMLValueType.FLOAT, basePath .. "#minDeltaY", "Min. delta Y from center point")
107 schema:register(XMLValueType.NODE_INDEX, basePath .. "#minDeltaYComponent", "Min. delta Y reference node")
108 schema:register(XMLValueType.COLOR, basePath .. "#color", "Hose color")
109 schema:register(XMLValueType.STRING, basePath .. "#adapterType", "Adapter type name")
110 schema:register(XMLValueType.NODE_INDEX, basePath .. "#adapterNode", "Link node for detached adapter")
111 schema:register(XMLValueType.STRING, basePath .. "#outgoingAdapter", "Adapter type that is used for outgoing connection hose")
112 schema:register(XMLValueType.STRING, basePath .. "#socket", "Outgoing socket name to load")
113 schema:register(XMLValueType.COLOR, basePath .. "#socketColor", "Socket custom color")
114
115 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
116end

registerHoseTargetNodesXMLPaths

Description
Definition
registerHoseTargetNodesXMLPaths()
Code
72function ConnectionHoses.registerHoseTargetNodesXMLPaths(schema, basePath)
73 schema:register(XMLValueType.NODE_INDEX, basePath .. "#node", "Target node")
74 schema:register(XMLValueType.VECTOR_N, basePath .. "#attacherJointIndices", "List of corresponding attacher joint indices")
75 schema:register(XMLValueType.NODE_INDICES, basePath .. "#attacherJointNodes", "List of corresponding attacher joint nodes (i3dIdentifiers or paths separated by space)")
76 schema:register(XMLValueType.STRING, basePath .. "#type", "Hose type")
77 schema:register(XMLValueType.STRING, basePath .. "#specType", "Connection hose specialization type (if defined it needs to match the type of the other tool)")
78 schema:register(XMLValueType.FLOAT, basePath .. "#straighteningFactor", "Straightening Factor", 1)
79 schema:register(XMLValueType.VECTOR_3, basePath .. "#straighteningDirection", "Straightening direction", "0 0 1")
80 schema:register(XMLValueType.STRING, basePath .. "#socket", "Socket name to load")
81 schema:register(XMLValueType.COLOR, basePath .. "#socketColor", "Socket custom color")
82 schema:register(XMLValueType.STRING, basePath .. "#adapterType", "Adapter type to use", "DEFAULT")
83
84 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
85end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
166function ConnectionHoses.registerOverwrittenFunctions(vehicleType)
167 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadExtraDependentParts", ConnectionHoses.loadExtraDependentParts)
168 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateExtraDependentParts", ConnectionHoses.updateExtraDependentParts)
169end

retryHoseSkipNodeConnections

Description
Definition
retryHoseSkipNodeConnections()
Code
1472function ConnectionHoses:retryHoseSkipNodeConnections(updateToolConnections, excludeVehicle)
1473 if self.getAttachedImplements ~= nil then
1474 local attachedImplements = self:getAttachedImplements()
1475 for _, implement in ipairs(attachedImplements) do
1476 local object = implement.object
1477 if object ~= excludeVehicle then
1478 if object.connectHosesToAttacherVehicle ~= nil then
1479 object:connectHosesToAttacherVehicle(self, implement.inputJointDescIndex, implement.jointDescIndex, updateToolConnections, excludeVehicle)
1480 end
1481 end
1482 end
1483 end
1484end

updateAttachedConnectionHoses

Description
Definition
updateAttachedConnectionHoses()
Code
278function ConnectionHoses:updateAttachedConnectionHoses(attacherVehicle)
279 local spec = self.spec_connectionHoses
280 for i=1, #spec.updateableHoses do
281 local hose = spec.updateableHoses[i]
282 if hose.connectedObject == attacherVehicle then
283 if self.updateLoopIndex == hose.connectedObject.updateLoopIndex then
284 self:updateConnectionHose(hose, i)
285 end
286 end
287 end
288end

updateConnectionHose

Description
Definition
updateConnectionHose()
Code
292function ConnectionHoses:updateConnectionHose(hose, index)
293 -- determine control points for spline
294 local p0x, p0y, p0z = 0, 0, -hose.startStraightening
295 local p3x, p3y, p3z = localToLocal(hose.targetNode, hose.hoseNode, 0, 0, 0)
296 local p4x, p4y, p4z = localToLocal(hose.targetNode, hose.hoseNode, hose.endStraighteningDirection[1] * hose.endStraightening, hose.endStraighteningDirection[2] * hose.endStraightening, hose.endStraighteningDirection[3] * hose.endStraightening)
297
298 -- default position of middle node
299 local p2x, p2y, p2z
300
301 if hose.isWorldSpaceHose then
302 local w1x, w1y, w1z = getWorldTranslation(hose.hoseNode)
303 local w2x, w2y, w2z = getWorldTranslation(hose.targetNode)
304
305 p2x = (w1x + w2x) / 2
306 p2y = (w1y + w2y) / 2
307 p2z = (w1z + w2z) / 2
308 else
309 p2x = p3x / 2
310 p2y = p3y / 2
311 p2z = p3z / 2
312 end
313
314 -- real distance between nodes
315 local d = MathUtil.vector3Length(p3x, p3y, p3z)
316
317 -- simple calculation of the center point -> low precicision, high performance
318 local lengthDifference = math.max(hose.length - d, 0)
319 local p2yStart = p2y
320 if not hose.isWorldSpaceHose then
321 local _
322 _, p2yStart, _ = localToWorld(hose.hoseNode, p2x, p2y, p2z)
323 end
324
325 p2y = p2y - math.max(lengthDifference, 0.04 * d)
326
327 if hose.isWorldSpaceHose then
328 if hose.minDeltaY ~= math.huge then
329 local x, y, z = worldToLocal(hose.minDeltaYComponent, p2x, p2y, p2z)
330 local _, yTarget, _ = localToLocal(hose.hoseNode, hose.minDeltaYComponent, 0, 0, 0)
331 p2x, p2y, p2z = localToWorld(hose.minDeltaYComponent, x, math.max(y, yTarget+hose.minDeltaY), z)
332 end
333
334 p2x, p2y, p2z = worldToLocal(hose.hoseNode, p2x, p2y, p2z)
335 end
336
337 local angle1, angle2 = self:getCenterPointAngle(hose.hoseNode, p2x, p2y, p2z, p3x, p3y, p3z, hose.isWorldSpaceHose)
338 local centerPointAngle = angle1+angle2
339 if centerPointAngle < hose.minCenterPointAngle then
340 p2x, p2y, p2z = self:getCenterPointAngleRegulation(hose.hoseNode, p2x, p2y, p2z, p3x, p3y, p3z, angle1, angle2, hose.minCenterPointAngle, hose.isWorldSpaceHose)
341 end
342
343 if hose.minCenterPointOffset ~= nil and hose.maxCenterPointOffset ~= nil then
344 p2x = MathUtil.clamp(p2x, hose.minCenterPointOffset[1], hose.maxCenterPointOffset[1])
345 p2y = MathUtil.clamp(p2y, hose.minCenterPointOffset[2], hose.maxCenterPointOffset[2])
346 p2z = MathUtil.clamp(p2z, hose.minCenterPointOffset[3], hose.maxCenterPointOffset[3])
347 end
348
349 -- manipulate by parent component Y and Z velocity
350 local newX, newY, newZ = getWorldTranslation(hose.component)
351 if hose.lastComponentPosition == nil or hose.lastComponentVelocity == nil then
352 hose.lastComponentPosition = {newX, newY, newZ}
353 hose.lastComponentVelocity = {newX, newY, newZ}
354 end
355
356 local newVelX, newVelY, newVelZ = newX-hose.lastComponentPosition[1], newY-hose.lastComponentPosition[2], newZ-hose.lastComponentPosition[3]
357 hose.lastComponentPosition[1], hose.lastComponentPosition[2], hose.lastComponentPosition[3] = newX, newY, newZ
358
359 local velX, velY, velZ = newVelX-hose.lastComponentVelocity[1], newVelY-hose.lastComponentVelocity[2], newVelZ-hose.lastComponentVelocity[3]
360 hose.lastComponentVelocity[1], hose.lastComponentVelocity[2], hose.lastComponentVelocity[3] = newVelX, newVelY, newVelZ
361
362 local worldX, worldY, worldZ = getWorldTranslation(hose.hoseNode)
363 local _
364 _, velY, velZ = worldToLocal(hose.hoseNode, worldX+velX, worldY+velY, worldZ+velZ)
365
366 local _, wp2y, _ = localToWorld(hose.hoseNode, p2x, p2y, p2z)
367 local realLengthDifference = p2yStart - wp2y
368 velY = MathUtil.clamp(velY*-hose.dampingFactor, -hose.dampingRange, hose.dampingRange) * realLengthDifference
369 velZ = MathUtil.clamp(velZ*-hose.dampingFactor, -hose.dampingRange, hose.dampingRange) * realLengthDifference
370
371 velY = velY * 0.1 + hose.lastVelY * 0.9
372 velZ = velZ * 0.1 + hose.lastVelZ * 0.9
373
374 hose.lastVelY = velY
375 hose.lastVelZ = velZ
376
377 p2x, p2y, p2z = p2x, p2y+velY, p2z+velZ
378
379 -- on two point hoses we set the center point to 0 and the shader creates a two point catmull rom
380 if hose.isTwoPointHose then
381 p2x, p2y, p2z = 0, 0, 0
382 end
383
384 -- apply to shader
385 setShaderParameter(hose.hoseNode, "cv2", p2x, p2y, p2z, 0, false) -- center point
386 setShaderParameter(hose.hoseNode, "cv3", p3x, p3y, p3z, 0, false) -- target point
387 setShaderParameter(hose.hoseNode, "cv4", p4x, p4y, p4z, 1, false) -- straighter point
388
389 if VehicleDebug.state == VehicleDebug.DEBUG_ATTACHER_JOINTS then
390 if self:getIsActiveForInput() then
391 local realLength = MathUtil.vector3Length(p2x, p2y, p2z)
392 realLength = realLength + MathUtil.vector3Length(p2x-p3x, p2y-p3y, p2z-p3z)
393 renderText(0.5, 0.9-index*0.02, 0.0175, string.format("hose %s:", getName(hose.node)))
394 renderText(0.62, 0.9-index*0.02, 0.0175, string.format("directLength: %.2f configLength: %.2f realLength: %.2f angle: %.2f minAngle: %.2f", d, hose.length, realLength, math.deg(centerPointAngle), math.deg(hose.minCenterPointAngle)))
395
396 local x1,y1,z1 = localToWorld(hose.hoseNode, p0x, p0y, p0z)
397 local x2,y2,z2 = localToWorld(hose.hoseNode, 0, 0, 0)
398 drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0)
399
400 x1,y1,z1 = localToWorld(hose.hoseNode, 0, 0, 0)
401 x2,y2,z2 = localToWorld(hose.hoseNode, p2x, p2y, p2z)
402 drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0)
403
404 x1,y1,z1 = localToWorld(hose.hoseNode, p2x, p2y, p2z)
405 x2,y2,z2 = localToWorld(hose.hoseNode, p3x, p3y, p3z)
406 drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0)
407
408 x1,y1,z1 = localToWorld(hose.hoseNode, p3x, p3y, p3z)
409 x2,y2,z2 = localToWorld(hose.hoseNode, p4x, p4y, p4z)
410 drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0)
411
412 local x0,y0,z0 = localToWorld(hose.hoseNode, p0x, p0y, p0z)
413 x1,y1,z1 = localToWorld(hose.hoseNode, 0, 0, 0)
414 x2,y2,z2 = localToWorld(hose.hoseNode, p2x, p2y, p2z)
415 local x3,y3,z3 = localToWorld(hose.hoseNode, p3x, p3y, p3z)
416 local x4,y4,z4 = localToWorld(hose.hoseNode, p4x, p4y, p4z)
417 drawDebugPoint(x0,y0,z0, 1,0,0,1)
418 drawDebugPoint(x1,y1,z1, 1,0,0,1)
419 drawDebugPoint(x2,y2,z2, 1,0,0,1)
420 drawDebugPoint(x3,y3,z3, 1,0,0,1)
421 drawDebugPoint(x4,y4,z4, 1,0,0,1)
422
423 DebugUtil.drawDebugNode(hose.hoseNode)
424 DebugUtil.drawDebugNode(hose.targetNode)
425 end
426 end
427end

updateCustomHoseNode

Description
Definition
updateCustomHoseNode()
Code
1554function ConnectionHoses:updateCustomHoseNode(customHose, customTarget)
1555 setTranslation(customHose.node, localToLocal(customTarget.node, getParent(customHose.node), 0, 0, 0))
1556 setRotation(customHose.node, localRotationToLocal(customTarget.node, getParent(customHose.node), 0, 0, 0))
1557end

updateExtraDependentParts

Description
Definition
updateExtraDependentParts()
Code
1597function ConnectionHoses:updateExtraDependentParts(superFunc, part, dt)
1598 superFunc(self, part, dt)
1599
1600 if part.customHoseIndices ~= nil then
1601 local spec = self.spec_connectionHoses
1602 for i=1, #part.customHoseIndices do
1603 local customHoseIndex = part.customHoseIndices[i]
1604 local customHose = spec.customHoses[customHoseIndex]
1605 if customHose ~= nil and customHose.isActive then
1606 self:updateCustomHoseNode(customHose, customHose.connectedTarget)
1607 end
1608 end
1609 end
1610
1611 if part.customTargetIndices ~= nil then
1612 local spec = self.spec_connectionHoses
1613 for i=1, #part.customTargetIndices do
1614 local customTargetIndex = part.customTargetIndices[i]
1615 local customTarget = spec.customHoseTargets[customTargetIndex]
1616 if customTarget ~= nil and customTarget.isActive then
1617 self:updateCustomHoseNode(customTarget.connectedHose, customTarget)
1618 end
1619 end
1620 end
1621end

updateToolConnectionHose

Description
Definition
updateToolConnectionHose()
Code
1226function ConnectionHoses:updateToolConnectionHose(sourceObject, sourceHose, targetObject, targetHose, visibility)
1227 local spec = self.spec_connectionHoses
1228
1229 local function setTargetNodeTranslation(hose)
1230 if hose.originalNodeTranslation == nil then
1231 hose.originalNodeTranslation = {getTranslation(hose.node)}
1232 else
1233 setTranslation(hose.node, unpack(hose.originalNodeTranslation))
1234 end
1235 local wx, wy, wz = localToWorld(hose.node, 0, sourceHose.diameter*0.5, 0)
1236 local lx, ly, lz = worldToLocal(getParent(hose.node), wx, wy, wz)
1237 setTranslation(hose.node, lx, ly, lz)
1238 end
1239
1240 local toolConnectionHose = spec.targetNodeToToolConnection[targetHose.index]
1241 if toolConnectionHose ~= nil then
1242 local opositTargetIndex = toolConnectionHose.startTargetNodeIndex
1243 if opositTargetIndex == targetHose.index then
1244 opositTargetIndex = toolConnectionHose.endTargetNodeIndex
1245 end
1246 local opositTarget = spec.targetNodes[opositTargetIndex]
1247
1248 if opositTarget ~= nil then
1249 if visibility and toolConnectionHose.delayedMounting ~= nil and toolConnectionHose.delayedMounting.sourceHose.connectedObject == nil then
1250 local differentSource = toolConnectionHose.delayedMounting.sourceObject ~= sourceObject -- with the retryHoseSkipNodeConnections functionallity it can happen that the object is the same
1251 local sameType = toolConnectionHose.delayedMounting.sourceHose.type == sourceHose.type
1252 and toolConnectionHose.delayedMounting.sourceHose.specType == sourceHose.specType
1253 if differentSource and sameType then
1254 local x, y, z = localToLocal(targetHose.node, opositTarget.node, 0, 0, 0)
1255 local length = MathUtil.vector3Length(x, y, z)
1256
1257 if toolConnectionHose.additionalHose then
1258 local hose, _, _, _ = g_connectionHoseManager:getClonedHoseNode(sourceHose.type, sourceHose.hoseType, length, sourceHose.diameter, sourceHose.color, self.customEnvironment)
1259
1260 if hose ~= nil then
1261 link(targetHose.node, hose)
1262 setTranslation(hose, 0, 0, 0)
1263
1264 local dirX, dirY, dirZ = localToLocal(hose, opositTarget.node, 0, 0, 0)
1265 if dirX ~= 0 or dirY ~= nil or dirZ ~= nil then
1266 setDirection(hose, dirX, dirY, dirZ, 0, 0, 1)
1267
1268 setShaderParameter(hose, "cv0", 0, 0, -dirZ*0.5, 0, false)
1269 setShaderParameter(hose, "cv2", dirX*0.5+0.003, dirY*0.5, dirZ*0.5, 0, false) -- center point
1270 setShaderParameter(hose, "cv3", dirX-0.003, dirY, dirZ, 0, false) -- target point
1271 setShaderParameter(hose, "cv4", dirX-0.003, dirY, dirZ+dirZ*0.5, 0, false) -- end straightening point
1272 end
1273
1274 if toolConnectionHose.moveNodes then
1275 setTargetNodeTranslation(targetHose)
1276 setTargetNodeTranslation(opositTarget)
1277 end
1278
1279 sourceObject:addAllSubWashableNodes(hose)
1280
1281 toolConnectionHose.hoseNode = hose
1282 toolConnectionHose.hoseNodeObject = sourceObject
1283 else
1284 return false
1285 end
1286 end
1287
1288 toolConnectionHose.connected = true
1289
1290 if toolConnectionHose.mountingNode ~= nil then
1291 setVisibility(toolConnectionHose.mountingNode, true)
1292 end
1293
1294 -- connect the first attached hose to the tool connection
1295 if toolConnectionHose.delayedMounting ~= nil then
1296 toolConnectionHose.delayedUnmounting = {}
1297 table.insert(toolConnectionHose.delayedUnmounting, toolConnectionHose.delayedMounting)
1298 table.insert(toolConnectionHose.delayedUnmounting, {sourceObject=sourceObject, sourceHose=sourceHose, targetObject=targetObject, targetHose=targetHose})
1299
1300 local delayedHose = toolConnectionHose.delayedMounting
1301 toolConnectionHose.delayedMounting = nil
1302 delayedHose.sourceObject:connectHose(delayedHose.sourceHose, delayedHose.targetObject, delayedHose.targetHose, false)
1303 delayedHose.sourceObject:retryHoseSkipNodeConnections(false)
1304 end
1305
1306 return true
1307 end
1308 else
1309 if toolConnectionHose.connected then
1310 toolConnectionHose.connected = false
1311
1312 if toolConnectionHose.hoseNode ~= nil then
1313 toolConnectionHose.hoseNodeObject:removeAllSubWashableNodes(toolConnectionHose.hoseNode)
1314
1315 delete(toolConnectionHose.hoseNode)
1316 toolConnectionHose.hoseNode = nil
1317 toolConnectionHose.hoseNodeObject = nil
1318 end
1319
1320 if toolConnectionHose.mountingNode ~= nil then
1321 setVisibility(toolConnectionHose.mountingNode, false)
1322 end
1323
1324 -- remove the second hose connection from the tool connection
1325 -- but keep it as delayed mounting
1326 -- if is hose from skip node, completly remove it (will be recreated depending on sub attached tool)
1327 if toolConnectionHose.delayedUnmounting ~= nil then
1328 for _, hose in ipairs(toolConnectionHose.delayedUnmounting) do
1329 if sourceHose ~= hose.sourceHose then
1330 hose.sourceObject:disconnectHose(hose.sourceHose)
1331 if hose.sourceHose.isClonedSkipNodeHose == nil or not hose.sourceHose.isClonedSkipNodeHose then
1332 toolConnectionHose.delayedMounting = hose
1333 end
1334 end
1335 end
1336
1337 toolConnectionHose.delayedUnmounting = nil
1338 end
1339 end
1340 end
1341 end
1342 else
1343 return true
1344 end
1345
1346 return false
1347end