Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
ConnectionHoses
DescriptionSpecialization for loading materials from a vehicle config xml and applying them to given nodesFunctions
- addHoseTargetNodes
- addHoseToDelayedMountings
- connectHose
- connectHosesToAttacherVehicle
- connectHoseToSkipNode
- disconnectHose
- getCenterPointAngle
- getCenterPointAngleRegulation
- getClonedSkipHoseNode
- getConnectionHosesByInputAttacherJoint
- getConnectionTarget
- getIsConnectionHoseUsed
- getIsConnectionTargetUsed
- getIsSkipNodeAvailable
- loadHoseNode
- loadHoseSkipNode
- loadHoseTargetNode
- loadToolConnectorHoseNode
- onPostAttach
- onPreDetach
- onUpdateInterpolation
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- retryHoseSkipNodeConnections
- updateAttachedConnectionHoses
- updateConnectionHose
- updateToolConnectionHose
addHoseTargetNodes
DescriptionDefinitionaddHoseTargetNodes()Code
447 | function ConnectionHoses:addHoseTargetNodes(xmlFile, key) |
448 | local spec = self.spec_connectionHoses |
449 | |
450 | local i = 0 |
451 | while true do |
452 | local targetKey = string.format("%s(%d)", key, i) |
453 | if not hasXMLProperty(xmlFile, targetKey) then |
454 | break |
455 | end |
456 | local entry = {} |
457 | if self:loadHoseTargetNode(xmlFile, targetKey, entry) then |
458 | table.insert(spec.targetNodes, entry) |
459 | entry.index = #spec.targetNodes |
460 | |
461 | if spec.targetNodesByType[entry.type] == nil then |
462 | spec.targetNodesByType[entry.type] = {} |
463 | end |
464 | |
465 | table.insert(spec.targetNodesByType[entry.type], entry) |
466 | end |
467 | i = i + 1 |
468 | end |
469 | |
470 | -- return the index of the last added target |
471 | if i > 0 then |
472 | return #spec.targetNodes |
473 | end |
474 | end |
addHoseToDelayedMountings
DescriptionDefinitionaddHoseToDelayedMountings()Code
976 | function ConnectionHoses:addHoseToDelayedMountings(sourceObject, sourceHose, targetObject, targetHose) |
977 | local spec = self.spec_connectionHoses |
978 | |
979 | local toolConnectionHose = spec.targetNodeToToolConnection[targetHose.index] |
980 | if toolConnectionHose ~= nil and toolConnectionHose.delayedMounting == nil then |
981 | toolConnectionHose.delayedMounting = {sourceObject=sourceObject, sourceHose=sourceHose, targetObject=targetObject, targetHose=targetHose} |
982 | |
983 | local rootVehicle = self:getRootVehicle() |
984 | rootVehicle:retryHoseSkipNodeConnections(true, sourceObject) |
985 | end |
986 | end |
connectHose
DescriptionDefinitionconnectHose()Code
745 | function ConnectionHoses:connectHose(sourceHose, targetObject, targetHose, updateToolConnections) |
746 | local spec = self.spec_connectionHoses |
747 | |
748 | local doConnect = false |
749 | if updateToolConnections ~= nil and not updateToolConnections then |
750 | doConnect = true |
751 | else |
752 | if targetObject:updateToolConnectionHose(self, sourceHose, targetObject, targetHose, true) then |
753 | doConnect = true |
754 | else |
755 | -- on tool connections we wait until both ends are connected to a tool and then we connect the hoses |
756 | targetObject:addHoseToDelayedMountings(self, sourceHose, targetObject, targetHose) |
757 | end |
758 | end |
759 | |
760 | if doConnect then |
761 | targetHose.connectedObject = self |
762 | sourceHose.connectedObject = targetObject |
763 | |
764 | sourceHose.targetHose = targetHose |
765 | |
766 | local node, referenceNode |
767 | if sourceHose.adapterName ~= nil then |
768 | if sourceHose.adapterName ~= "NONE" then |
769 | node, referenceNode = g_connectionHoseManager:getClonedAdapterNode(targetHose.type, sourceHose.adapterName) |
770 | end |
771 | elseif targetHose.adapterName ~= "NONE" then |
772 | node, referenceNode = g_connectionHoseManager:getClonedAdapterNode(targetHose.type, targetHose.adapterName) |
773 | end |
774 | |
775 | if node ~= nil then |
776 | link(g_connectionHoseManager:getSocketTarget(targetHose.socket, targetHose.node), node) |
777 | setTranslation(node, 0,0,0) |
778 | setRotation(node, 0,0,0) |
779 | targetObject:addAllSubWashableNodes(node) |
780 | |
781 | targetHose.adapter.node = node |
782 | targetHose.adapter.refNode = referenceNode |
783 | targetHose.adapter.isLinked = true |
784 | end |
785 | |
786 | sourceHose.targetNode = targetHose.adapter.refNode |
787 | |
788 | setVisibility(sourceHose.hoseNode, true) |
789 | setShaderParameter(sourceHose.hoseNode, "cv0", 0, 0, -sourceHose.startStraightening, 1, false) |
790 | sourceHose.endStraightening = sourceHose.endStraighteningBase * targetHose.straighteningFactor |
791 | |
792 | ObjectChangeUtil.setObjectChanges(targetHose.objectChanges, true) |
793 | ObjectChangeUtil.setObjectChanges(sourceHose.objectChanges, true) |
794 | |
795 | g_connectionHoseManager:openSocket(targetHose.socket) |
796 | |
797 | -- if we don't use a adapter to connect we use the dirt of the attacher vehicle to have a seamless transition |
798 | if targetHose.adapter == nil or targetHose.adapter.node == targetHose.adapter.refNode then |
799 | self:removeAllSubWashableNodes(sourceHose.hoseNode) |
800 | targetObject:addAllSubWashableNodes(sourceHose.hoseNode) |
801 | end |
802 | |
803 | table.insert(spec.updateableHoses, sourceHose) |
804 | self:updateConnectionHose(sourceHose, 0) |
805 | end |
806 | end |
connectHosesToAttacherVehicle
DescriptionDefinitionconnectHosesToAttacherVehicle()Code
1060 | function ConnectionHoses:connectHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex, updateToolConnections, excludeVehicle) |
1061 | if attacherVehicle.getConnectionTarget ~= nil then |
1062 | local hoses = self:getConnectionHosesByInputAttacherJoint(inputJointDescIndex) |
1063 | for _, hose in ipairs(hoses) do |
1064 | if not self:getIsConnectionHoseUsed(hose) then |
1065 | local firstValidTarget, isSkipNode = attacherVehicle:getConnectionTarget(jointDescIndex, hose.type) |
1066 | if firstValidTarget ~= nil then |
1067 | if not isSkipNode then |
1068 | self:connectHose(hose, attacherVehicle, firstValidTarget, updateToolConnections) |
1069 | else |
1070 | self:connectHoseToSkipNode(hose, attacherVehicle, firstValidTarget) |
1071 | end |
1072 | end |
1073 | end |
1074 | end |
1075 | |
1076 | --try to connect the hoses of attached implements, maybe the connection is now valid since we got another skip node |
1077 | self:retryHoseSkipNodeConnections(updateToolConnections, excludeVehicle) |
1078 | end |
1079 | end |
connectHoseToSkipNode
DescriptionDefinitionconnectHoseToSkipNode()Code
990 | function ConnectionHoses:connectHoseToSkipNode(sourceHose, targetObject, skipNode, childHose, childVehicle) |
991 | local spec = self.spec_connectionHoses |
992 | |
993 | skipNode.connectedObject = self |
994 | sourceHose.connectedObject = targetObject |
995 | |
996 | sourceHose.targetHose = skipNode |
997 | sourceHose.targetNode = skipNode.node |
998 | |
999 | setVisibility(sourceHose.hoseNode, true) |
1000 | setShaderParameter(sourceHose.hoseNode, "cv0", 0, 0, -sourceHose.startStraightening, 1, false) |
1001 | |
1002 | ObjectChangeUtil.setObjectChanges(sourceHose.objectChanges, true) |
1003 | |
1004 | self:addAllSubWashableNodes(sourceHose.hoseNode) |
1005 | |
1006 | sourceHose.childVehicle = childVehicle |
1007 | sourceHose.childHose = childHose |
1008 | |
1009 | if self.getAttacherVehicle ~= nil then |
1010 | local attacherVehicle1 = self:getAttacherVehicle() |
1011 | if attacherVehicle1.getAttacherVehicle ~= nil then |
1012 | local attacherVehicle2 = attacherVehicle1:getAttacherVehicle() |
1013 | if attacherVehicle2 ~= nil then |
1014 | |
1015 | local attacherJointIndex = attacherVehicle2:getAttacherJointIndexFromObject(attacherVehicle1) |
1016 | local implement = attacherVehicle1:getImplementFromAttacherJointIndex(attacherJointIndex) |
1017 | |
1018 | if implement.inputJointDescIndex == skipNode.inputAttacherJointIndex then |
1019 | local firstValidTarget, isSkipNode = attacherVehicle2:getConnectionTarget(attacherJointIndex, skipNode.type) |
1020 | if firstValidTarget ~= nil then |
1021 | local hose = attacherVehicle1:getClonedSkipHoseNode(sourceHose, skipNode) |
1022 | if not isSkipNode then |
1023 | attacherVehicle1:connectHose(hose, attacherVehicle2, firstValidTarget) |
1024 | else |
1025 | attacherVehicle1:connectHoseToSkipNode(hose, attacherVehicle2, firstValidTarget, sourceHose, attacherVehicle1) |
1026 | end |
1027 | |
1028 | if skipNode.parentHose ~= nil then |
1029 | delete(skipNode.parentHose.hoseNode) |
1030 | end |
1031 | skipNode.parentVehicle = attacherVehicle1 |
1032 | skipNode.parentHose = hose |
1033 | |
1034 | sourceHose.parentVehicle = attacherVehicle1 |
1035 | sourceHose.parentHose = hose |
1036 | |
1037 | hose.childVehicle = self |
1038 | hose.childHose = sourceHose |
1039 | else |
1040 | --same hose is still active, just update the relations |
1041 | if skipNode.parentHose ~= nil then |
1042 | sourceHose.parentVehicle = skipNode.parentVehicle |
1043 | sourceHose.parentHose = skipNode.parentHose |
1044 | |
1045 | sourceHose.parentHose.childVehicle = self |
1046 | sourceHose.parentHose.childHose = sourceHose |
1047 | end |
1048 | end |
1049 | end |
1050 | end |
1051 | end |
1052 | end |
1053 | |
1054 | table.insert(spec.updateableHoses, sourceHose) |
1055 | self:updateConnectionHose(sourceHose, 0) |
1056 | end |
disconnectHose
DescriptionDefinitiondisconnectHose()Code
810 | function ConnectionHoses:disconnectHose(hose) |
811 | local spec = self.spec_connectionHoses |
812 | local target = hose.targetHose |
813 | if target ~= nil then |
814 | hose.connectedObject:updateToolConnectionHose(self, hose, hose.connectedObject, target, false) |
815 | |
816 | local hoseHasSkipNodeTarget = target.isSkipNode ~= nil and target.isSkipNode |
817 | local hoseIsFromSkipNodeTarget = hose.isClonedSkipNodeHose ~= nil and hose.isClonedSkipNodeHose |
818 | if hoseHasSkipNodeTarget or hoseIsFromSkipNodeTarget then |
819 | --remove all skip node connections recursively in both directions |
820 | if hose.parentVehicle ~= nil and hose.parentHose ~= nil then |
821 | hose.parentHose.childVehicle = nil |
822 | hose.parentHose.childHose = nil |
823 | hose.parentVehicle:disconnectHose(hose.parentHose) |
824 | end |
825 | |
826 | if hose.childVehicle ~= nil and hose.childHose ~= nil then |
827 | hose.childHose.parentVehicle = nil |
828 | hose.childHose.parentHose = nil |
829 | hose.childVehicle:disconnectHose(hose.childHose) |
830 | end |
831 | |
832 | setVisibility(hose.hoseNode, false) |
833 | target.parentHose = nil |
834 | else |
835 | if target.adapter.isLinked ~= nil and target.adapter.isLinked then |
836 | hose.connectedObject:removeAllSubWashableNodes(target.adapter.node) |
837 | delete(target.adapter.node) |
838 | |
839 | target.adapter.node = target.node |
840 | target.adapter.refNode = target.node |
841 | target.adapter.isLinked = false |
842 | end |
843 | |
844 | setVisibility(hose.hoseNode, false) |
845 | ObjectChangeUtil.setObjectChanges(target.objectChanges, false) |
846 | ObjectChangeUtil.setObjectChanges(hose.objectChanges, false) |
847 | |
848 | g_connectionHoseManager:closeSocket(target.socket) |
849 | end |
850 | |
851 | if target.adapter == nil or target.adapter.node == target.adapter.refNode then |
852 | hose.connectedObject:removeAllSubWashableNodes(hose.hoseNode) |
853 | self:addAllSubWashableNodes(hose.hoseNode) |
854 | end |
855 | |
856 | target.connectedObject = nil |
857 | hose.connectedObject = nil |
858 | hose.targetHose = nil |
859 | |
860 | ListUtil.removeElementFromList(spec.updateableHoses, hose) |
861 | end |
862 | end |
getCenterPointAngle
DescriptionDefinitiongetCenterPointAngle()Code
339 | function ConnectionHoses:getCenterPointAngle(node, cX, cY, cZ, eX, eY, eZ, useWorldSpace) |
340 | local lengthStartToCenter = MathUtil.vector3Length(cX, cY, cZ) |
341 | local lengthCenterToEnd = math.abs(MathUtil.vector3Length(cX-eX, cY-eY, cZ-eZ)) |
342 | |
343 | local _, sY, _ = getWorldTranslation(node) |
344 | if useWorldSpace then |
345 | _, cY, _ = localToWorld(node, cX, cY, cZ) |
346 | _, eY, _ = localToWorld(node, eX, eY, eZ) |
347 | else |
348 | sY = 0 |
349 | end |
350 | |
351 | local lengthStartToCenter2 = sY-cY |
352 | local lengthCenterToEnd2 = eY-cY |
353 | |
354 | local angle1 = math.acos(lengthStartToCenter2/lengthStartToCenter) |
355 | local angle2 = math.acos(lengthCenterToEnd2/lengthCenterToEnd) |
356 | |
357 | return angle1, angle2 |
358 | end |
getCenterPointAngleRegulation
DescriptionDefinitiongetCenterPointAngleRegulation()Code
362 | function ConnectionHoses:getCenterPointAngleRegulation(node, cX, cY, cZ, eX, eY, eZ, angle1, angle2, targetAngle, useWorldSpace) |
363 | local sX, sY, sZ = getWorldTranslation(node) |
364 | if useWorldSpace then |
365 | cX, _, cZ = localToWorld(node, cX, cY, cZ) |
366 | eX, _, eZ = localToWorld(node, eX, eY, eZ) |
367 | else |
368 | sX, sY, sZ = 0, 0, 0 |
369 | end |
370 | |
371 | local startCenterLength = MathUtil.vector2Length(sX-cX, sZ-cZ) |
372 | local centerEndLength = MathUtil.vector2Length(eX-cX, eZ-cZ) |
373 | |
374 | local pct = angle1/(angle1+angle2) |
375 | local alpha = math.pi * 0.5 - (pct * targetAngle) |
376 | |
377 | local newY1 = math.tan(alpha) * startCenterLength |
378 | local newY2 = math.tan(alpha) * centerEndLength |
379 | |
380 | local newY = (newY1 + newY2) / 2 |
381 | |
382 | if useWorldSpace then |
383 | return worldToLocal(node, cX, sY-newY, cZ) |
384 | else |
385 | return cX, sY-newY, cZ |
386 | end |
387 | end |
getClonedSkipHoseNode
DescriptionDefinitiongetClonedSkipHoseNode()Code
613 | function ConnectionHoses:getClonedSkipHoseNode(sourceHose, skipNode) |
614 | local clonedHose = {} |
615 | |
616 | clonedHose.isClonedSkipNodeHose = true |
617 | |
618 | clonedHose.type = sourceHose.type |
619 | clonedHose.hoseType = sourceHose.hoseType |
620 | clonedHose.node = skipNode.node |
621 | |
622 | clonedHose.component = self:getParentComponent(skipNode.node) |
623 | clonedHose.lastVelY = 0 |
624 | clonedHose.lastVelZ = 0 |
625 | clonedHose.dampingRange = 0.05 |
626 | clonedHose.dampingFactor = 50 |
627 | |
628 | clonedHose.minDeltaYComponent = self:getParentComponent(skipNode.node) |
629 | clonedHose.minDeltaY = math.huge |
630 | |
631 | clonedHose.length = skipNode.length or sourceHose.length |
632 | clonedHose.diameter = sourceHose.diameter |
633 | clonedHose.isTwoPointHose = skipNode.isTwoPointHose |
634 | |
635 | clonedHose.color = sourceHose.color |
636 | |
637 | local hose, startStraightening, endStraightening, minCenterPointAngle = g_connectionHoseManager:getClonedHoseNode(clonedHose.type, clonedHose.hoseType, clonedHose.length, clonedHose.diameter, clonedHose.color) |
638 | |
639 | if hose ~= nil then |
640 | link(clonedHose.node, hose) |
641 | setTranslation(hose, 0, 0, 0) |
642 | setRotation(hose, 0, 0, 0) |
643 | |
644 | clonedHose.hoseNode = hose |
645 | clonedHose.startStraightening = startStraightening |
646 | clonedHose.endStraightening = endStraightening |
647 | clonedHose.endStraighteningBase = endStraightening |
648 | clonedHose.minCenterPointAngle = minCenterPointAngle |
649 | |
650 | setVisibility(clonedHose.hoseNode, false) |
651 | else |
652 | g_logManager:xmlWarning(self.configFileName, "Unable to find connection hose with length '%.2f' and diameter '%.2f' in '%s'", clonedHose.length, clonedHose.diameter, "skipHoseClone") |
653 | return false |
654 | end |
655 | |
656 | clonedHose.objectChanges = {} |
657 | |
658 | return clonedHose |
659 | end |
getConnectionHosesByInputAttacherJoint
DescriptionDefinitiongetConnectionHosesByInputAttacherJoint()Code
733 | function ConnectionHoses:getConnectionHosesByInputAttacherJoint(inputJointDescIndex) |
734 | local spec = self.spec_connectionHoses |
735 | |
736 | if spec.hoseNodesByInputAttacher[inputJointDescIndex] ~= nil then |
737 | return spec.hoseNodesByInputAttacher[inputJointDescIndex] |
738 | end |
739 | |
740 | return {} |
741 | end |
getConnectionTarget
DescriptionDefinitiongetConnectionTarget()Code
663 | function ConnectionHoses:getConnectionTarget(attacherJointIndex, type, excludeToolConnections) |
664 | local spec = self.spec_connectionHoses |
665 | if #spec.targetNodes == 0 and #spec.hoseSkipNodes == 0 then |
666 | return nil |
667 | end |
668 | |
669 | local nodes = spec.targetNodesByType[type] |
670 | if nodes ~= nil then |
671 | for _, node in ipairs(nodes) do |
672 | if node.attacherJointIndices[attacherJointIndex] ~= nil then |
673 | if not self:getIsConnectionTargetUsed(node) then |
674 | local toolConnectionHose = spec.targetNodeToToolConnection[node.index] |
675 | if toolConnectionHose ~= nil and excludeToolConnections ~= nil and excludeToolConnections then |
676 | if toolConnectionHose.delayedMounting == nil then |
677 | return nil |
678 | end |
679 | end |
680 | |
681 | return node, false |
682 | end |
683 | end |
684 | end |
685 | end |
686 | |
687 | nodes = spec.hoseSkipNodeByType[type] |
688 | if nodes ~= nil then |
689 | for _, node in ipairs(nodes) do |
690 | if self:getIsSkipNodeAvailable(node) then |
691 | return node, true |
692 | end |
693 | end |
694 | end |
695 | |
696 | return nil |
697 | end |
getIsConnectionHoseUsed
DescriptionDefinitiongetIsConnectionHoseUsed()Code
707 | function ConnectionHoses:getIsConnectionHoseUsed(desc) |
708 | return desc.connectedObject ~= nil |
709 | end |
getIsConnectionTargetUsed
DescriptionDefinitiongetIsConnectionTargetUsed()Code
701 | function ConnectionHoses:getIsConnectionTargetUsed(desc) |
702 | return desc.connectedObject ~= nil |
703 | end |
getIsSkipNodeAvailable
DescriptionDefinitiongetIsSkipNodeAvailable()Code
713 | function ConnectionHoses:getIsSkipNodeAvailable(skipNode) |
714 | if self.getAttacherVehicle == nil then |
715 | return false |
716 | end |
717 | |
718 | local attacherVehicle = self:getAttacherVehicle() |
719 | if attacherVehicle ~= nil then |
720 | local attacherJointIndex = attacherVehicle:getAttacherJointIndexFromObject(self) |
721 | local implement = attacherVehicle:getImplementFromAttacherJointIndex(attacherJointIndex) |
722 | |
723 | if implement.inputJointDescIndex == skipNode.inputAttacherJointIndex then |
724 | return attacherVehicle:getConnectionTarget(attacherJointIndex, skipNode.type, true) ~= nil or skipNode.parentHose ~= nil |
725 | end |
726 | end |
727 | |
728 | return false |
729 | end |
loadHoseNode
DescriptionDefinitionloadHoseNode()Code
524 | function ConnectionHoses:loadHoseNode(xmlFile, hoseKey, entry) |
525 | local inputAttacherJointIndices = {StringUtil.getVectorFromString(getXMLString(xmlFile, hoseKey .. "#inputAttacherJointIndices"))} |
526 | entry.inputAttacherJointIndices = {} |
527 | for _, v in ipairs(inputAttacherJointIndices) do |
528 | entry.inputAttacherJointIndices[v] = v |
529 | end |
530 | |
531 | entry.type = getXMLString(xmlFile, hoseKey .. "#type") |
532 | if entry.type == nil then |
533 | g_logManager:xmlWarning(self.configFileName, "Missing type attribute in '%s'", hoseKey) |
534 | return false |
535 | end |
536 | |
537 | entry.hoseType = Utils.getNoNil(getXMLString(xmlFile, hoseKey .. "#hoseType"), "DEFAULT") |
538 | entry.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, hoseKey .. "#node"), self.i3dMappings) |
539 | if entry.node == nil then |
540 | g_logManager:xmlWarning(self.configFileName, "Missing node for connection hose '%s'", hoseKey) |
541 | return false |
542 | end |
543 | |
544 | entry.isTwoPointHose = Utils.getNoNil(getXMLBool(xmlFile, hoseKey .. "#isTwoPointHose"), false) |
545 | entry.isWorldSpaceHose = Utils.getNoNil(getXMLBool(xmlFile, hoseKey .. "#isWorldSpaceHose"), true) |
546 | |
547 | entry.component = self:getParentComponent(entry.node) |
548 | entry.lastVelY = 0 |
549 | entry.lastVelZ = 0 |
550 | entry.dampingRange = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#dampingRange"), 0.05) |
551 | entry.dampingFactor = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#dampingFactor"), 50) |
552 | |
553 | entry.length = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#length"), 3) |
554 | entry.diameter = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#diameter"), 0.02) |
555 | entry.straighteningFactor = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#straighteningFactor"), 1) |
556 | entry.minCenterPointAngle = Utils.getNoNilRad(getXMLFloat(xmlFile, hoseKey .. "#minCenterPointAngle"), nil) |
557 | |
558 | entry.minCenterPointOffset = StringUtil.getVectorNFromString(getXMLString(xmlFile, hoseKey .. "#minCenterPointOffset"), 3) |
559 | entry.maxCenterPointOffset = StringUtil.getVectorNFromString(getXMLString(xmlFile, hoseKey .. "#maxCenterPointOffset"), 3) |
560 | |
561 | if entry.minCenterPointOffset ~= nil and entry.maxCenterPointOffset ~= nil then |
562 | for i=1, 3 do |
563 | if entry.minCenterPointOffset[i] == 0 then |
564 | entry.minCenterPointOffset[i] = -math.huge |
565 | end |
566 | |
567 | if entry.maxCenterPointOffset[i] == 0 then |
568 | entry.maxCenterPointOffset[i] = math.huge |
569 | end |
570 | end |
571 | end |
572 | |
573 | entry.minDeltaY = Utils.getNoNil(getXMLFloat(xmlFile, hoseKey .. "#minDeltaY"), math.huge) |
574 | entry.minDeltaYComponent = Utils.getNoNil(I3DUtil.indexToObject(self.components, getXMLString(xmlFile, hoseKey .. "#minDeltaYComponent"), self.i3dMappings), entry.component) |
575 | |
576 | local colorValueStr = getXMLString(xmlFile, hoseKey.."#color") |
577 | entry.color = g_brandColorManager:getBrandColorByName(colorValueStr) |
578 | if entry.color == nil then |
579 | entry.color = StringUtil.getVectorNFromString(colorValueStr, 4) |
580 | end |
581 | |
582 | local hose, startStraightening, endStraightening, minCenterPointAngle = g_connectionHoseManager:getClonedHoseNode(entry.type, entry.hoseType, entry.length, entry.diameter, entry.color) |
583 | |
584 | if hose ~= nil then |
585 | link(entry.node, hose) |
586 | setTranslation(hose, 0, 0, 0) |
587 | setRotation(hose, 0, 0, 0) |
588 | |
589 | entry.hoseNode = hose |
590 | entry.startStraightening = startStraightening * entry.straighteningFactor |
591 | entry.endStraightening = endStraightening |
592 | entry.endStraighteningBase = endStraightening |
593 | entry.minCenterPointAngle = entry.minCenterPointAngle or minCenterPointAngle |
594 | |
595 | setVisibility(entry.hoseNode, false) |
596 | else |
597 | g_logManager:xmlWarning(self.configFileName, "Unable to find connection hose with length '%.2f' and diameter '%.2f' in '%s'", entry.length, entry.diameter, hoseKey) |
598 | return false |
599 | end |
600 | |
601 | entry.adapterName = getXMLString(xmlFile, hoseKey .. "#adapterType") |
602 | |
603 | entry.objectChanges = {} |
604 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, hoseKey, entry.objectChanges, self.components, self) |
605 | ObjectChangeUtil.setObjectChanges(entry.objectChanges, false) |
606 | |
607 | return true |
608 | end |
loadHoseSkipNode
DescriptionDefinitionloadHoseSkipNode()Code
391 | function ConnectionHoses:loadHoseSkipNode(xmlFile, targetKey, entry) |
392 | entry.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, targetKey .. "#node"), self.i3dMappings) |
393 | |
394 | if entry.node == nil then |
395 | g_logManager:xmlWarning(self.configFileName, "Missing node for hose skip node '%s'", targetKey) |
396 | return false |
397 | end |
398 | |
399 | entry.inputAttacherJointIndex = Utils.getNoNil(getXMLInt(xmlFile, targetKey .. "#inputAttacherJointIndex"), 1) |
400 | entry.attacherJointIndex = Utils.getNoNil(getXMLInt(xmlFile, targetKey .. "#attacherJointIndex"), 1) |
401 | |
402 | entry.type = getXMLString(xmlFile, targetKey .. "#type") |
403 | |
404 | if entry.type == nil then |
405 | g_logManager:xmlWarning(self.configFileName, "Missing type for hose skip node '%s'", targetKey) |
406 | return false |
407 | end |
408 | |
409 | entry.length = getXMLFloat(xmlFile, targetKey .. "#length") |
410 | entry.isTwoPointHose = Utils.getNoNil(getXMLBool(xmlFile, targetKey .. "#isTwoPointHose"), false) |
411 | |
412 | entry.isSkipNode = true |
413 | |
414 | return true |
415 | end |
loadHoseTargetNode
DescriptionDefinitionloadHoseTargetNode()Code
478 | function ConnectionHoses:loadHoseTargetNode(xmlFile, targetKey, entry) |
479 | entry.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, targetKey .. "#node"), self.i3dMappings) |
480 | |
481 | if entry.node == nil then |
482 | g_logManager:xmlWarning(self.configFileName, "Missing node for connection hose target '%s'", targetKey) |
483 | return false |
484 | end |
485 | |
486 | local attacherJointIndices = {StringUtil.getVectorFromString(getXMLString(xmlFile, targetKey .. "#attacherJointIndices"))} |
487 | entry.attacherJointIndices = {} |
488 | for _, v in ipairs(attacherJointIndices) do |
489 | entry.attacherJointIndices[v] = v |
490 | end |
491 | |
492 | entry.type = getXMLString(xmlFile, targetKey .. "#type") |
493 | entry.straighteningFactor = Utils.getNoNil(getXMLFloat(xmlFile, targetKey .. "#straighteningFactor"), 1) |
494 | |
495 | local socketName = getXMLString(xmlFile, targetKey .. "#socket") |
496 | if socketName ~= nil then |
497 | entry.socket = g_connectionHoseManager:linkSocketToNode(socketName, entry.node) |
498 | end |
499 | |
500 | if entry.type ~= nil then |
501 | entry.adapterName = Utils.getNoNil(getXMLString(xmlFile, targetKey .. "#adapterType"), "DEFAULT") |
502 | |
503 | -- empty adapter with target node as reference |
504 | -- will be replaced with the real adapter on connecting |
505 | if entry.adapter == nil then |
506 | entry.adapter = {} |
507 | entry.adapter.node = entry.node |
508 | entry.adapter.refNode = entry.node |
509 | end |
510 | |
511 | entry.objectChanges = {} |
512 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, targetKey, entry.objectChanges, self.components, self) |
513 | ObjectChangeUtil.setObjectChanges(entry.objectChanges, false) |
514 | else |
515 | g_logManager:xmlWarning(self.configFileName, "Missing type for '%s'", targetKey) |
516 | return false |
517 | end |
518 | |
519 | return true |
520 | end |
loadToolConnectorHoseNode
DescriptionDefinitionloadToolConnectorHoseNode()Code
419 | function ConnectionHoses:loadToolConnectorHoseNode(xmlFile, targetKey, entry) |
420 | local key = string.format("%s.startTarget", targetKey) |
421 | entry.startTargetNodeIndex = self:addHoseTargetNodes(xmlFile, key) |
422 | |
423 | if entry.startTargetNodeIndex == nil then |
424 | g_logManager:xmlWarning(self.configFileName, "startTarget is missing for tool connection hose '%s'", targetKey) |
425 | return false |
426 | end |
427 | |
428 | key = string.format("%s.endTarget", targetKey) |
429 | entry.endTargetNodeIndex = self:addHoseTargetNodes(xmlFile, key) |
430 | |
431 | if entry.endTargetNodeIndex == nil then |
432 | g_logManager:xmlWarning(self.configFileName, "endTarget is missing for tool connection hose '%s'", targetKey) |
433 | return false |
434 | end |
435 | |
436 | entry.mountingNode = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, targetKey .. "#mountingNode"), self.i3dMappings) |
437 | |
438 | if entry.mountingNode ~= nil then |
439 | setVisibility(entry.mountingNode, false) |
440 | end |
441 | |
442 | return true |
443 | end |
onPostAttach
DescriptionDefinitiononPostAttach()Code
1099 | function ConnectionHoses:onPostAttach(attacherVehicle, inputJointDescIndex, jointDescIndex) |
1100 | self:connectHosesToAttacherVehicle(attacherVehicle, inputJointDescIndex, jointDescIndex) |
1101 | end |
onPreDetach
DescriptionDefinitiononPreDetach()Code
1105 | function ConnectionHoses:onPreDetach(attacherVehicle, implement) |
1106 | local spec = self.spec_connectionHoses |
1107 | |
1108 | local hoses = self:getConnectionHosesByInputAttacherJoint(self:getActiveInputAttacherJointDescIndex()) |
1109 | for _, hose in ipairs(hoses) do |
1110 | self:disconnectHose(hose) |
1111 | end |
1112 | |
1113 | for _, hose in ipairs(spec.updateableHoses) do |
1114 | if hose.connectedObject == attacherVehicle then |
1115 | self:disconnectHose(hose) |
1116 | end |
1117 | end |
1118 | |
1119 | -- remove delayed mounting if we detach the implement |
1120 | local attacherVehicleSpec = attacherVehicle.spec_connectionHoses |
1121 | if attacherVehicleSpec ~= nil then |
1122 | for _, toolConnector in pairs(attacherVehicleSpec.toolConnectorHoses) do |
1123 | if toolConnector.delayedMounting ~= nil then |
1124 | if toolConnector.delayedMounting.sourceObject == self then |
1125 | toolConnector.delayedMounting = nil |
1126 | end |
1127 | end |
1128 | end |
1129 | end |
1130 | end |
onUpdateInterpolation
DescriptionDefinitiononUpdateInterpolation()Code
171 | function ConnectionHoses:onUpdateInterpolation(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
172 | if self.isClient then |
173 | local spec = self.spec_connectionHoses |
174 | for index, hose in ipairs(spec.updateableHoses) do |
175 | if self.updateLoopIndex == hose.connectedObject.updateLoopIndex then |
176 | self:updateConnectionHose(hose, index) |
177 | end |
178 | end |
179 | |
180 | if self.getAttachedImplements ~= nil then |
181 | for _, implement in ipairs(self:getAttachedImplements()) do |
182 | if implement.object.updateAttachedConnectionHoses ~= nil then |
183 | implement.object:updateAttachedConnectionHoses(self) |
184 | end |
185 | end |
186 | end |
187 | end |
188 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
15 | function ConnectionHoses.prerequisitesPresent(specializations) |
16 | return true |
17 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
48 | function ConnectionHoses.registerEventListeners(vehicleType) |
49 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", ConnectionHoses) |
50 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateInterpolation", ConnectionHoses) |
51 | SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", ConnectionHoses) |
52 | SpecializationUtil.registerEventListener(vehicleType, "onPreDetach", ConnectionHoses) |
53 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
21 | function ConnectionHoses.registerFunctions(vehicleType) |
22 | SpecializationUtil.registerFunction(vehicleType, "updateAttachedConnectionHoses", ConnectionHoses.updateAttachedConnectionHoses) |
23 | SpecializationUtil.registerFunction(vehicleType, "updateConnectionHose", ConnectionHoses.updateConnectionHose) |
24 | SpecializationUtil.registerFunction(vehicleType, "getCenterPointAngle", ConnectionHoses.getCenterPointAngle) |
25 | SpecializationUtil.registerFunction(vehicleType, "getCenterPointAngleRegulation", ConnectionHoses.getCenterPointAngleRegulation) |
26 | SpecializationUtil.registerFunction(vehicleType, "loadHoseSkipNode", ConnectionHoses.loadHoseSkipNode) |
27 | SpecializationUtil.registerFunction(vehicleType, "loadToolConnectorHoseNode", ConnectionHoses.loadToolConnectorHoseNode) |
28 | SpecializationUtil.registerFunction(vehicleType, "addHoseTargetNodes", ConnectionHoses.addHoseTargetNodes) |
29 | SpecializationUtil.registerFunction(vehicleType, "loadHoseTargetNode", ConnectionHoses.loadHoseTargetNode) |
30 | SpecializationUtil.registerFunction(vehicleType, "loadHoseNode", ConnectionHoses.loadHoseNode) |
31 | SpecializationUtil.registerFunction(vehicleType, "getClonedSkipHoseNode", ConnectionHoses.getClonedSkipHoseNode) |
32 | SpecializationUtil.registerFunction(vehicleType, "getConnectionTarget", ConnectionHoses.getConnectionTarget) |
33 | SpecializationUtil.registerFunction(vehicleType, "getIsConnectionTargetUsed", ConnectionHoses.getIsConnectionTargetUsed) |
34 | SpecializationUtil.registerFunction(vehicleType, "getIsConnectionHoseUsed", ConnectionHoses.getIsConnectionHoseUsed) |
35 | SpecializationUtil.registerFunction(vehicleType, "getIsSkipNodeAvailable", ConnectionHoses.getIsSkipNodeAvailable) |
36 | SpecializationUtil.registerFunction(vehicleType, "getConnectionHosesByInputAttacherJoint", ConnectionHoses.getConnectionHosesByInputAttacherJoint) |
37 | SpecializationUtil.registerFunction(vehicleType, "connectHose", ConnectionHoses.connectHose) |
38 | SpecializationUtil.registerFunction(vehicleType, "disconnectHose", ConnectionHoses.disconnectHose) |
39 | SpecializationUtil.registerFunction(vehicleType, "updateToolConnectionHose", ConnectionHoses.updateToolConnectionHose) |
40 | SpecializationUtil.registerFunction(vehicleType, "addHoseToDelayedMountings", ConnectionHoses.addHoseToDelayedMountings) |
41 | SpecializationUtil.registerFunction(vehicleType, "connectHoseToSkipNode", ConnectionHoses.connectHoseToSkipNode) |
42 | SpecializationUtil.registerFunction(vehicleType, "connectHosesToAttacherVehicle", ConnectionHoses.connectHosesToAttacherVehicle) |
43 | SpecializationUtil.registerFunction(vehicleType, "retryHoseSkipNodeConnections", ConnectionHoses.retryHoseSkipNodeConnections) |
44 | end |
retryHoseSkipNodeConnections
DescriptionDefinitionretryHoseSkipNodeConnections()Code
1083 | function ConnectionHoses:retryHoseSkipNodeConnections(updateToolConnections, excludeVehicle) |
1084 | if self.getAttachedImplements ~= nil then |
1085 | local attachedImplements = self:getAttachedImplements() |
1086 | for _, implement in ipairs(attachedImplements) do |
1087 | local object = implement.object |
1088 | if object ~= excludeVehicle then |
1089 | if object.connectHosesToAttacherVehicle ~= nil then |
1090 | object:connectHosesToAttacherVehicle(self, implement.inputJointDescIndex, implement.jointDescIndex, updateToolConnections, excludeVehicle) |
1091 | end |
1092 | end |
1093 | end |
1094 | end |
1095 | end |
updateAttachedConnectionHoses
DescriptionDefinitionupdateAttachedConnectionHoses()Code
192 | function ConnectionHoses:updateAttachedConnectionHoses(attacherVehicle) |
193 | if self.isClient then |
194 | local spec = self.spec_connectionHoses |
195 | for index, hose in ipairs(spec.updateableHoses) do |
196 | if hose.connectedObject == attacherVehicle then |
197 | if self.updateLoopIndex == hose.connectedObject.updateLoopIndex then |
198 | self:updateConnectionHose(hose, index) |
199 | end |
200 | end |
201 | end |
202 | end |
203 | end |
updateConnectionHose
DescriptionDefinitionupdateConnectionHose()Code
207 | function ConnectionHoses:updateConnectionHose(hose, index) |
208 | -- determine control points for spline |
209 | local p0x, p0y, p0z = 0, 0, -hose.startStraightening |
210 | local p3x, p3y, p3z = localToLocal(hose.targetNode, hose.hoseNode, 0,0,0) |
211 | local p4x, p4y, p4z = localToLocal(hose.targetNode, hose.hoseNode, 0,0, hose.endStraightening) |
212 | |
213 | -- default position of middle node |
214 | local p2x |
215 | local p2y |
216 | local p2z |
217 | |
218 | if hose.isWorldSpaceHose then |
219 | local w1x, w1y, w1z = getWorldTranslation(hose.hoseNode) |
220 | local w2x, w2y, w2z = getWorldTranslation(hose.targetNode) |
221 | |
222 | p2x = (w1x + w2x) / 2 |
223 | p2y = (w1y + w2y) / 2 |
224 | p2z = (w1z + w2z) / 2 |
225 | else |
226 | p2x = p3x / 2 |
227 | p2y = p3y / 2 |
228 | p2z = p3z / 2 |
229 | end |
230 | |
231 | -- real distance between nodes |
232 | local d = MathUtil.vector3Length(p3x, p3y, p3z) |
233 | |
234 | -- simple calculation of the center point -> low precicision, high performance |
235 | local lengthDifference = math.max(hose.length - d, 0) |
236 | p2y = p2y - math.max(lengthDifference, 0.04 * d) |
237 | |
238 | if hose.isWorldSpaceHose then |
239 | if hose.minDeltaY ~= math.huge then |
240 | local x, y, z = worldToLocal(hose.minDeltaYComponent, p2x, p2y, p2z) |
241 | local _, yTarget, _ = localToLocal(hose.minDeltaYComponent, hose.hoseNode, 0, 0, 0) |
242 | p2x, p2y, p2z = localToWorld(hose.minDeltaYComponent, x, math.max(y, -yTarget+hose.minDeltaY), z) |
243 | end |
244 | |
245 | p2x, p2y, p2z = worldToLocal(hose.hoseNode, p2x, p2y, p2z) |
246 | end |
247 | |
248 | local angle1, angle2 = self:getCenterPointAngle(hose.hoseNode, p2x, p2y, p2z, p3x, p3y, p3z, hose.isWorldSpaceHose) |
249 | local centerPointAngle = angle1+angle2 |
250 | if centerPointAngle < hose.minCenterPointAngle then |
251 | p2x, p2y, p2z = self:getCenterPointAngleRegulation(hose.hoseNode, p2x, p2y, p2z, p3x, p3y, p3z, angle1, angle2, hose.minCenterPointAngle, hose.isWorldSpaceHose) |
252 | end |
253 | |
254 | if hose.minCenterPointOffset ~= nil and hose.maxCenterPointOffset ~= nil then |
255 | p2x = MathUtil.clamp(p2x, hose.minCenterPointOffset[1], hose.maxCenterPointOffset[1]) |
256 | p2y = MathUtil.clamp(p2y, hose.minCenterPointOffset[2], hose.maxCenterPointOffset[2]) |
257 | p2z = MathUtil.clamp(p2z, hose.minCenterPointOffset[3], hose.maxCenterPointOffset[3]) |
258 | end |
259 | |
260 | -- manipulate by parent component Y and Z velocity |
261 | local newX, newY, newZ = getWorldTranslation(hose.component) |
262 | if hose.lastComponentPosition == nil or hose.lastComponentVelocity == nil then |
263 | hose.lastComponentPosition = {newX, newY, newZ} |
264 | hose.lastComponentVelocity = {newX, newY, newZ} |
265 | end |
266 | |
267 | local newVelX, newVelY, newVelZ = newX-hose.lastComponentPosition[1], newY-hose.lastComponentPosition[2], newZ-hose.lastComponentPosition[3] |
268 | hose.lastComponentPosition[1], hose.lastComponentPosition[2], hose.lastComponentPosition[3] = newX, newY, newZ |
269 | |
270 | local velX, velY, velZ = newVelX-hose.lastComponentVelocity[1], newVelY-hose.lastComponentVelocity[2], newVelZ-hose.lastComponentVelocity[3] |
271 | hose.lastComponentVelocity[1], hose.lastComponentVelocity[2], hose.lastComponentVelocity[3] = newVelX, newVelY, newVelZ |
272 | |
273 | local worldX, worldY, worldZ = getWorldTranslation(hose.hoseNode) |
274 | _, velY, velZ = worldToLocal(hose.hoseNode, worldX+velX, worldY+velY, worldZ+velZ) |
275 | |
276 | velY = MathUtil.clamp(velY*-hose.dampingFactor, -hose.dampingRange, hose.dampingRange) * lengthDifference |
277 | velZ = MathUtil.clamp(velZ*-hose.dampingFactor, -hose.dampingRange, hose.dampingRange) * lengthDifference |
278 | |
279 | velY = velY * 0.1 + hose.lastVelY * 0.9 |
280 | velZ = velZ * 0.1 + hose.lastVelZ * 0.9 |
281 | |
282 | hose.lastVelY = velY |
283 | hose.lastVelZ = velZ |
284 | |
285 | p2x, p2y, p2z = p2x, p2y+velY, p2z+velZ |
286 | |
287 | -- on two point hoses we set the center point to 0 and the shader creates a two point catmull rom |
288 | if hose.isTwoPointHose then |
289 | p2x, p2y, p2z = 0, 0, 0 |
290 | end |
291 | |
292 | -- apply to shader |
293 | setShaderParameter(hose.hoseNode, "cv2", p2x, p2y, p2z, 0, false) -- center point |
294 | setShaderParameter(hose.hoseNode, "cv3", p3x, p3y, p3z, 0, false) -- target point |
295 | setShaderParameter(hose.hoseNode, "cv4", p4x, p4y, p4z, 1, false) -- straighter point |
296 | |
297 | if VehicleDebug.state == VehicleDebug.DEBUG_ATTACHER_JOINTS then |
298 | if self:getIsActiveForInput() then |
299 | local realLength = MathUtil.vector3Length(p2x, p2y, p2z) |
300 | realLength = realLength + MathUtil.vector3Length(p2x-p3x, p2y-p3y, p2z-p3z) |
301 | renderText(0.5, 0.9-index*0.02, 0.0175, string.format("hose %s:", getName(hose.node))) |
302 | 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))) |
303 | |
304 | local x1,y1,z1 = localToWorld(hose.hoseNode, p0x, p0y, p0z) |
305 | local x2,y2,z2 = localToWorld(hose.hoseNode, 0, 0, 0) |
306 | drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0) |
307 | |
308 | x1,y1,z1 = localToWorld(hose.hoseNode, 0, 0, 0) |
309 | x2,y2,z2 = localToWorld(hose.hoseNode, p2x, p2y, p2z) |
310 | drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0) |
311 | |
312 | x1,y1,z1 = localToWorld(hose.hoseNode, p2x, p2y, p2z) |
313 | x2,y2,z2 = localToWorld(hose.hoseNode, p3x, p3y, p3z) |
314 | drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0) |
315 | |
316 | x1,y1,z1 = localToWorld(hose.hoseNode, p3x, p3y, p3z) |
317 | x2,y2,z2 = localToWorld(hose.hoseNode, p4x, p4y, p4z) |
318 | drawDebugLine(x1,y1,z1, 1,0,0, x2,y2,z2, 0,1,0) |
319 | |
320 | local x0,y0,z0 = localToWorld(hose.hoseNode, p0x, p0y, p0z) |
321 | x1,y1,z1 = localToWorld(hose.hoseNode, 0, 0, 0) |
322 | x2,y2,z2 = localToWorld(hose.hoseNode, p2x, p2y, p2z) |
323 | local x3,y3,z3 = localToWorld(hose.hoseNode, p3x, p3y, p3z) |
324 | local x4,y4,z4 = localToWorld(hose.hoseNode, p4x, p4y, p4z) |
325 | drawDebugPoint(x0,y0,z0, 1,0,0,1) |
326 | drawDebugPoint(x1,y1,z1, 1,0,0,1) |
327 | drawDebugPoint(x2,y2,z2, 1,0,0,1) |
328 | drawDebugPoint(x3,y3,z3, 1,0,0,1) |
329 | drawDebugPoint(x4,y4,z4, 1,0,0,1) |
330 | |
331 | DebugUtil.drawDebugNode(hose.hoseNode) |
332 | DebugUtil.drawDebugNode(hose.targetNode) |
333 | end |
334 | end |
335 | end |
updateToolConnectionHose
DescriptionDefinitionupdateToolConnectionHose()Code
866 | function ConnectionHoses:updateToolConnectionHose(sourceObject, sourceHose, targetObject, targetHose, visibility) |
867 | local spec = self.spec_connectionHoses |
868 | |
869 | local toolConnectionHose = spec.targetNodeToToolConnection[targetHose.index] |
870 | if toolConnectionHose ~= nil then |
871 | local opositTargetIndex = toolConnectionHose.startTargetNodeIndex |
872 | if opositTargetIndex == targetHose.index then |
873 | opositTargetIndex = toolConnectionHose.endTargetNodeIndex |
874 | end |
875 | local opositTarget = spec.targetNodes[opositTargetIndex] |
876 | |
877 | if opositTarget ~= nil then |
878 | if visibility and toolConnectionHose.delayedMounting ~= nil then |
879 | local differentSource = toolConnectionHose.delayedMounting.sourceObject ~= sourceObject -- with the retryHoseSkipNodeConnections functionallity it can happen that the object is the same |
880 | local sameType = toolConnectionHose.delayedMounting.sourceHose.type == sourceHose.type |
881 | if differentSource and sameType then |
882 | local x, y, z = localToLocal(targetHose.node, opositTarget.node, 0, 0, 0) |
883 | local length = MathUtil.vector3Length(x, y, z) |
884 | |
885 | local hose, _, _, _ = g_connectionHoseManager:getClonedHoseNode(sourceHose.type, sourceHose.hoseType, length, sourceHose.diameter, sourceHose.color) |
886 | |
887 | if hose ~= nil then |
888 | link(targetHose.node, hose) |
889 | setTranslation(hose, 0, 0, 0) |
890 | |
891 | local dirX, dirY, dirZ = localToLocal(hose, opositTarget.node, 0, 0, 0) |
892 | setDirection(hose, dirX, dirY, dirZ, 0, 0, 1) |
893 | |
894 | setShaderParameter(hose, "cv0", 0, 0, -dirZ*0.5, 0, false) |
895 | setShaderParameter(hose, "cv2", dirX*0.5+0.003, dirY*0.5, dirZ*0.5, 0, false) -- center point |
896 | setShaderParameter(hose, "cv3", dirX-0.003, dirY, dirZ, 0, false) -- target point |
897 | setShaderParameter(hose, "cv4", dirX-0.003, dirY, dirZ+dirZ*0.5, 0, false) -- end straightening point |
898 | |
899 | local function setTargetNodeTranslation(hose) |
900 | if hose.originalNodeTranslation == nil then |
901 | hose.originalNodeTranslation = {getTranslation(hose.node)} |
902 | else |
903 | setTranslation(hose.node, unpack(hose.originalNodeTranslation)) |
904 | end |
905 | local wx, wy, wz = localToWorld(hose.node, 0, sourceHose.diameter*0.5, 0) |
906 | local lx, ly, lz = worldToLocal(getParent(hose.node), wx, wy, wz) |
907 | setTranslation(hose.node, lx, ly, lz) |
908 | end |
909 | |
910 | setTargetNodeTranslation(targetHose) |
911 | setTargetNodeTranslation(opositTarget) |
912 | |
913 | self:addAllSubWashableNodes(hose) |
914 | |
915 | toolConnectionHose.hoseNode = hose |
916 | |
917 | if toolConnectionHose.mountingNode ~= nil then |
918 | setVisibility(toolConnectionHose.mountingNode, true) |
919 | end |
920 | |
921 | -- connect the first attached hose to the tool connection |
922 | if toolConnectionHose.delayedMounting ~= nil then |
923 | toolConnectionHose.delayedUnmounting = {} |
924 | table.insert(toolConnectionHose.delayedUnmounting, toolConnectionHose.delayedMounting) |
925 | table.insert(toolConnectionHose.delayedUnmounting, {sourceObject=sourceObject, sourceHose=sourceHose, targetObject=targetObject, targetHose=targetHose}) |
926 | |
927 | local delayedHose = toolConnectionHose.delayedMounting |
928 | toolConnectionHose.delayedMounting = nil |
929 | delayedHose.sourceObject:connectHose(delayedHose.sourceHose, delayedHose.targetObject, delayedHose.targetHose, false) |
930 | delayedHose.sourceObject:retryHoseSkipNodeConnections(false) |
931 | end |
932 | |
933 | return true |
934 | else |
935 | return false |
936 | end |
937 | end |
938 | else |
939 | if toolConnectionHose.hoseNode ~= nil then |
940 | self:removeWashableNode(toolConnectionHose.hoseNode) |
941 | |
942 | delete(toolConnectionHose.hoseNode) |
943 | toolConnectionHose.hoseNode = nil |
944 | |
945 | if toolConnectionHose.mountingNode ~= nil then |
946 | setVisibility(toolConnectionHose.mountingNode, false) |
947 | end |
948 | |
949 | -- remove the second hose connection from the tool connection |
950 | -- but keep it as delayed mounting |
951 | -- if is hose from skip node, completly remove it (will be recreated depending on sub attached tool) |
952 | if toolConnectionHose.delayedUnmounting ~= nil then |
953 | for _, hose in ipairs(toolConnectionHose.delayedUnmounting) do |
954 | if sourceHose ~= hose.sourceHose then |
955 | hose.sourceObject:disconnectHose(hose.sourceHose) |
956 | if hose.sourceHose.isClonedSkipNodeHose == nil or not hose.sourceHose.isClonedSkipNodeHose then |
957 | toolConnectionHose.delayedMounting = hose |
958 | end |
959 | end |
960 | end |
961 | |
962 | toolConnectionHose.delayedUnmounting = nil |
963 | end |
964 | end |
965 | end |
966 | end |
967 | else |
968 | return true |
969 | end |
970 | |
971 | return false |
972 | end |