LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

PowerTakeOffs

Description
Specialization for vehicles with power takeoffs (PTOs), both output (e.g. tractor) and input (e.g. tool) ones
Functions

attachPowerTakeOff

Description
Definition
attachPowerTakeOff()
Code
642function PowerTakeOffs:attachPowerTakeOff(attachableObject, inputJointDescIndex, jointDescIndex)
643 local spec = self.spec_powerTakeOffs
644 local outputs = self:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
645
646 for _, output in ipairs(outputs) do
647 if attachableObject.getInputPowerTakeOffsByJointDescIndexAndName ~= nil then
648 local inputs = attachableObject:getInputPowerTakeOffsByJointDescIndexAndName(inputJointDescIndex, output.ptoName)
649 for _, input in ipairs(inputs) do
650 output.connectedInput = input
651 output.connectedVehicle = attachableObject
652 input.connectedVehicle = self
653 input.connectedOutput = output
654
655 table.insert(spec.delayedPowerTakeOffsMountings, {jointDescIndex=jointDescIndex, input=input, output=output})
656 end
657 end
658 end
659
660 return true
661end

attachTypedPowerTakeOff

Description
Definition
attachTypedPowerTakeOff()
Code
999function PowerTakeOffs:attachTypedPowerTakeOff(powerTakeOff, output)
1000 if self:validatePowerTakeOffAttachment(powerTakeOff, output) then
1001 link(output.outputNode, powerTakeOff.linkNode)
1002 link(powerTakeOff.inputNode, powerTakeOff.startNode)
1003
1004 setTranslation(powerTakeOff.linkNode, 0, 0, powerTakeOff.zOffset)
1005 setTranslation(powerTakeOff.startNode, 0, 0, -powerTakeOff.zOffset)
1006
1007 self:updatePowerTakeOff(powerTakeOff, 0)
1008 self:updatePowerTakeOffLength(powerTakeOff)
1009
1010 setVisibility(powerTakeOff.linkNode, true)
1011 setVisibility(powerTakeOff.startNode, true)
1012 end
1013end

checkPowerTakeOffCollision

Description
Check if the power take off colliding with the attacher joint if no trans node is defined -> detach if collision has been detected
Definition
checkPowerTakeOffCollision()
Code
695function PowerTakeOffs:checkPowerTakeOffCollision(attacherJointNode, jointDescIndex, isTrailerAttacher)
696 -- we assume that the pto is only able to collide with the drawbar on trailer attacher joints, not on implement joints etc
697 if isTrailerAttacher then
698 local ptoOutputs = self:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
699 if ptoOutputs ~= nil and #ptoOutputs > 0 then
700 local ptoOutput = ptoOutputs[1]
701 local ptoInput = ptoOutput.connectedInput
702 if ptoInput ~= nil then
703 local _, y, _ = localToLocal(ptoOutput.outputNode, attacherJointNode, 0, 0, 0)
704 if (ptoInput.aboveAttacher and y < 0) or (not ptoInput.aboveAttacher and y > 0) then
705 self:detachPowerTakeOff(self, nil, jointDescIndex)
706 end
707 end
708 end
709 end
710end

detachPowerTakeOff

Description
Definition
detachPowerTakeOff()
Code
665function PowerTakeOffs:detachPowerTakeOff(detachingVehicle, implement, jointDescIndex)
666 local spec = self.spec_powerTakeOffs
667 -- clear delayed mountings
668 spec.delayedPowerTakeOffsMountings = {}
669
670 local outputs = detachingVehicle:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex or implement.jointDescIndex)
671
672 for _, output in ipairs(outputs) do
673 if output.connectedInput ~= nil then
674 local input = output.connectedInput
675
676 if input.detachFunc ~= nil then
677 input.detachFunc(self, input, output)
678 end
679
680 input.connectedVehicle = nil
681 input.connectedOutput = nil
682 output.connectedVehicle = nil
683 output.connectedInput = nil
684
685 ObjectChangeUtil.setObjectChanges(input.objectChanges, false)
686 ObjectChangeUtil.setObjectChanges(output.objectChanges, false)
687 end
688 end
689
690 return true
691end

detachTypedPowerTakeOff

Description
Definition
detachTypedPowerTakeOff()
Code
1017function PowerTakeOffs:detachTypedPowerTakeOff(powerTakeOff, output)
1018 self:parkPowerTakeOff(powerTakeOff)
1019end

getInputPowerTakeOffs

Description
Definition
getInputPowerTakeOffs()
Code
630function PowerTakeOffs:getInputPowerTakeOffs()
631 return self.spec_powerTakeOffs.inputPowerTakeOffs
632end

getInputPowerTakeOffsByJointDescIndexAndName

Description
Definition
getInputPowerTakeOffsByJointDescIndexAndName()
Code
600function PowerTakeOffs:getInputPowerTakeOffsByJointDescIndexAndName(jointDescIndex, ptoName)
601 local retInputs = {}
602
603 local spec = self.spec_powerTakeOffs
604 for _, input in pairs(spec.inputPowerTakeOffs) do
605 if input.inputAttacherJointIndices[jointDescIndex] ~= nil then
606 if input.ptoName == ptoName then
607 table.insert(retInputs, input)
608 end
609 end
610 end
611
612 if #retInputs == 0 then
613 for _, output in pairs(spec.outputPowerTakeOffs) do
614 if output.skipToInputAttacherIndex == jointDescIndex then
615 for index, _ in pairs(output.attacherJointIndices) do
616 local implement = self:getImplementFromAttacherJointIndex(index)
617 if implement ~= nil then
618 retInputs = implement.object:getInputPowerTakeOffsByJointDescIndexAndName(implement.inputJointDescIndex, ptoName)
619 end
620 end
621 end
622 end
623 end
624
625 return retInputs
626end

getIsPowerTakeOffActive

Description
Definition
getIsPowerTakeOffActive()
Code
636function PowerTakeOffs:getIsPowerTakeOffActive()
637 return false
638end

getOutputPowerTakeOffs

Description
Definition
getOutputPowerTakeOffs()
Code
594function PowerTakeOffs:getOutputPowerTakeOffs()
595 return self.spec_powerTakeOffs.outputPowerTakeOffs
596end

getOutputPowerTakeOffsByJointDescIndex

Description
Definition
getOutputPowerTakeOffsByJointDescIndex()
Code
566function PowerTakeOffs:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
567 local retOutputs = {}
568
569 local spec = self.spec_powerTakeOffs
570 for _, output in pairs(spec.outputPowerTakeOffs) do
571 if output.attacherJointIndices[jointDescIndex] ~= nil then
572 table.insert(retOutputs, output)
573 end
574 end
575
576 if #retOutputs > 0 then
577 for _, output in ipairs(retOutputs) do
578 if output.skipToInputAttacherIndex ~= nil then
579 local secondAttacherVehicle = self:getAttacherVehicle()
580 if secondAttacherVehicle ~= nil then
581 local ownImplement = secondAttacherVehicle:getImplementByObject(self)
582 retOutputs = secondAttacherVehicle:getOutputPowerTakeOffsByJointDescIndex(ownImplement.jointDescIndex)
583 break
584 end
585 end
586 end
587 end
588
589 return retOutputs
590end

getPowerTakeOffConfigIndex

Description
Definition
getPowerTakeOffConfigIndex()
Code
365function PowerTakeOffs:getPowerTakeOffConfigIndex()
366 return 1
367end

initSpecialization

Description
Definition
initSpecialization()
Code
25function PowerTakeOffs.initSpecialization()
26 local schema = Vehicle.xmlSchema
27 schema:setXMLSpecializationType("PowerTakeOffs")
28
29 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration(?)")
30 PowerTakeOffs.registerXMLPaths(schema, "vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration(?)")
31 PowerTakeOffs.registerXMLPaths(schema, "vehicle.powerTakeOffs")
32
33 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_TOOL_XML_KEY .. ".powerTakeOffs#indices", "PTOs to update")
34 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_TOOL_XML_KEY .. ".powerTakeOffs#localIndices", "Local PTOs to update")
35 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_PART_XML_KEY .. ".powerTakeOffs#indices", "PTOs to update")
36 schema:register(XMLValueType.VECTOR_N, Cylindered.MOVING_PART_XML_KEY .. ".powerTakeOffs#localIndices", "Local PTOs to update")
37
38 schema:register(XMLValueType.BOOL, "vehicle.powerTakeOffs#ignoreInvalidJointIndices", "Do not display warning if attacher joint index could not be found. Can be useful if attacher joints change due to configurations", false)
39 schema:register(XMLValueType.FLOAT, "vehicle.powerTakeOffs#maxUpdateDistance", "Max. distance to vehicle root to update power take offs", PowerTakeOffs.DEFAULT_MAX_UPDATE_DISTANCE)
40
41 schema:setXMLSpecializationType()
42
43 local powerTakeOffXMLSchema = XMLSchema.new("powerTakeOff")
44 PowerTakeOffs.xmlSchema = powerTakeOffXMLSchema
45
46 powerTakeOffXMLSchema:register(XMLValueType.STRING, "powerTakeOff#filename", "Path to i3d file")
47 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.startNode#node", "Start node")
48 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.linkNode#node", "Link node")
49 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff#size", "Height of pto", 0.19)
50 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff#minLength", "Minimum length of pto", 0.6)
51 powerTakeOffXMLSchema:register(XMLValueType.ANGLE, "powerTakeOff#maxAngle", "Max. angle between start and end", 45)
52 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff#zOffset", "Z axis offset of end node", 0)
53 powerTakeOffXMLSchema:register(XMLValueType.STRING, "powerTakeOff#colorShaderParameter", "Color shader parameter")
54 powerTakeOffXMLSchema:register(XMLValueType.STRING, "powerTakeOff#decalColorShaderParameter", "Decal color shader parameter")
55
56 AnimationManager.registerAnimationNodesXMLPaths(powerTakeOffXMLSchema, "powerTakeOff.animationNodes")
57
58 powerTakeOffXMLSchema:register(XMLValueType.BOOL, "powerTakeOff#isSingleJoint", "Is single joint PTO", false)
59 powerTakeOffXMLSchema:register(XMLValueType.BOOL, "powerTakeOff#isDoubleJoint", "Is double joint PTO", false)
60
61 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.startJoint#node", "(Single Joint) Start joint node")
62 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.endJoint#node", "(Single Joint) End joint node")
63
64 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.scalePart#node", "(Single|Double Joint) Scale part node")
65 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.scalePart#referenceNode", "(Single|Double Joint) Scale part reference node")
66
67 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.translationPart#node", "(Single|Double Joint) translation part node")
68 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.translationPart#referenceNode", "(Single|Double Joint) translation part reference node")
69 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff.translationPart#length", "(Single|Double Joint) translation part length", 0.4)
70
71 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.translationPart.decal#node", "(Single|Double Joint) translation part decal node")
72 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff.translationPart.decal#size", "(Single|Double Joint) translation part decal size", 0.1)
73 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff.translationPart.decal#offset", "(Single|Double Joint) translation part decal offset", 0.05)
74 powerTakeOffXMLSchema:register(XMLValueType.FLOAT, "powerTakeOff.translationPart.decal#minOffset", "(Single|Double Joint) translation part decal minOffset", 0.01)
75
76 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.startJoint1#node", "(Double Joint) Start joint 1")
77 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.startJoint2#node", "(Double Joint) Start joint 2")
78
79 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.endJoint1#node", "(Double Joint) End joint 1")
80 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.endJoint1#referenceNode", "(Double Joint) End joint 1 reference node")
81 powerTakeOffXMLSchema:register(XMLValueType.NODE_INDEX, "powerTakeOff.endJoint2#node", "(Double Joint) End joint 2")
82end

loadBasicPowerTakeOff

Description
Definition
loadBasicPowerTakeOff()
Code
967function PowerTakeOffs:loadBasicPowerTakeOff(powerTakeOff, xmlFile, rootNode)
968 powerTakeOff.startNode = xmlFile:getValue("powerTakeOff.startNode#node", nil, rootNode)
969 powerTakeOff.linkNode = xmlFile:getValue("powerTakeOff.linkNode#node", nil, rootNode)
970
971 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
972 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
973end

loadDoubleJointPowerTakeOff

Description
Definition
loadDoubleJointPowerTakeOff()
Code
905function PowerTakeOffs:loadDoubleJointPowerTakeOff(powerTakeOff, xmlFile, rootNode)
906 powerTakeOff.startJoint1 = xmlFile:getValue("powerTakeOff.startJoint1#node", nil, rootNode)
907 powerTakeOff.startJoint2 = xmlFile:getValue("powerTakeOff.startJoint2#node", nil, rootNode)
908
909 powerTakeOff.scalePart = xmlFile:getValue("powerTakeOff.scalePart#node", nil, rootNode)
910 powerTakeOff.scalePartRef = xmlFile:getValue("powerTakeOff.scalePart#referenceNode", nil, rootNode)
911 local _, _, dis = localToLocal(powerTakeOff.scalePartRef, powerTakeOff.scalePart, 0, 0, 0)
912 powerTakeOff.scalePartBaseDistance = dis
913
914 powerTakeOff.translationPart = xmlFile:getValue("powerTakeOff.translationPart#node", nil, rootNode)
915 powerTakeOff.translationPartRef = xmlFile:getValue("powerTakeOff.translationPart#referenceNode", nil, rootNode)
916 powerTakeOff.translationPartLength = xmlFile:getValue("powerTakeOff.translationPart#length", 0.4)
917
918 powerTakeOff.decal = xmlFile:getValue("powerTakeOff.translationPart.decal#node", nil, rootNode)
919 powerTakeOff.decalSize = xmlFile:getValue("powerTakeOff.translationPart.decal#size", 0.1)
920 powerTakeOff.decalOffset = xmlFile:getValue("powerTakeOff.translationPart.decal#offset", 0.05)
921 powerTakeOff.decalMinOffset = xmlFile:getValue("powerTakeOff.translationPart.decal#minOffset", 0.01)
922
923 powerTakeOff.endJoint1 = xmlFile:getValue("powerTakeOff.endJoint1#node", nil, rootNode)
924 powerTakeOff.endJoint1Ref = xmlFile:getValue("powerTakeOff.endJoint1#referenceNode", nil, rootNode)
925
926 powerTakeOff.endJoint2 = xmlFile:getValue("powerTakeOff.endJoint2#node", nil, rootNode)
927 powerTakeOff.linkNode = xmlFile:getValue("powerTakeOff.linkNode#node", nil, rootNode)
928
929 local _, _, betweenLength = localToLocal(powerTakeOff.translationPart, powerTakeOff.translationPartRef, 0, 0, 0)
930 local _, _, ptoLength = localToLocal(powerTakeOff.startNode, powerTakeOff.linkNode, 0, 0, 0)
931 powerTakeOff.betweenLength = math.abs(betweenLength)
932 powerTakeOff.connectorLength = math.abs(ptoLength) - math.abs(betweenLength)
933
934 setTranslation(powerTakeOff.linkNode, 0, 0, 0)
935 setRotation(powerTakeOff.linkNode, 0, 0, 0)
936
937 powerTakeOff.updateFunc = PowerTakeOffs.updateDoubleJointPowerTakeOff
938 powerTakeOff.updateDistanceFunc = PowerTakeOffs.updateDistanceOfTypedPowerTakeOff
939 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
940 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
941end

loadExtraDependentParts

Description
Definition
loadExtraDependentParts()
Code
1047function PowerTakeOffs:loadExtraDependentParts(superFunc, xmlFile, baseName, entry)
1048 if not superFunc(self, xmlFile, baseName, entry) then
1049 return false
1050 end
1051
1052 local indices = xmlFile:getValue(baseName.. ".powerTakeOffs#indices", nil, true)
1053 if indices ~= nil then
1054 entry.powerTakeOffs = {}
1055
1056 for i=1, #indices do
1057 table.insert(entry.powerTakeOffs, indices[i])
1058 end
1059 end
1060
1061 local localIndices = xmlFile:getValue(baseName.. ".powerTakeOffs#localIndices", nil, true)
1062 if localIndices ~= nil then
1063 entry.localPowerTakeOffs = {}
1064
1065 for i=1, #localIndices do
1066 table.insert(entry.localPowerTakeOffs, localIndices[i])
1067 end
1068 end
1069
1070 return true
1071end

loadInputPowerTakeOff

Description
Definition
loadInputPowerTakeOff()
Code
441function PowerTakeOffs:loadInputPowerTakeOff(xmlFile, baseName, powerTakeOffInput)
442 local inputNode = xmlFile:getValue(baseName.."#inputNode", nil, self.components, self.i3dMappings)
443 if inputNode == nil then
444 Logging.xmlWarning(xmlFile, "Pto input needs to have a valid 'inputNode' in '%s'", baseName)
445 return false
446 end
447
448 local inputAttacherJointIndices = {}
449 local inputAttacherJointIndicesRaw = xmlFile:getValue(baseName .. "#inputAttacherJointIndices", nil, true)
450
451 if inputAttacherJointIndicesRaw == nil then
452 Logging.xmlWarning(xmlFile, "Pto output needs to have valid 'inputAttacherJointIndices' in '%s'", baseName)
453 return false
454 else
455 for _, index in ipairs(inputAttacherJointIndicesRaw) do
456 inputAttacherJointIndices[index] = true
457 end
458 end
459
460 powerTakeOffInput.inputNode = inputNode
461 powerTakeOffInput.detachNode = xmlFile:getValue(baseName.."#detachNode", nil, self.components, self.i3dMappings)
462 powerTakeOffInput.inputAttacherJointIndices = inputAttacherJointIndices
463
464 powerTakeOffInput.aboveAttacher = xmlFile:getValue(baseName.."#aboveAttacher", true)
465
466 powerTakeOffInput.color = xmlFile:getValue(baseName .. "#color", nil, true)
467 powerTakeOffInput.decalColor = xmlFile:getValue(baseName .. "#decalColor", nil, true)
468
469 powerTakeOffInput.ptoName = xmlFile:getValue(baseName .. "#ptoName", "DEFAULT_PTO")
470
471 powerTakeOffInput.objectChanges = {}
472 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, baseName, powerTakeOffInput.objectChanges, self.components, self)
473 ObjectChangeUtil.setObjectChanges(powerTakeOffInput.objectChanges, false)
474
475 local filename = xmlFile:getValue(baseName.. "#filename", "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
476 if filename ~= nil then
477 self:loadPowerTakeOffFromConfigFile(powerTakeOffInput, filename)
478 end
479
480 return true
481end

loadLocalPowerTakeOff

Description
Definition
loadLocalPowerTakeOff()
Code
485function PowerTakeOffs:loadLocalPowerTakeOff(xmlFile, baseName, powerTakeOffLocal)
486 powerTakeOffLocal.isLocal = true
487
488 powerTakeOffLocal.inputNode = xmlFile:getValue(baseName.."#startNode", nil, self.components, self.i3dMappings)
489 if powerTakeOffLocal.inputNode == nil then
490 Logging.xmlWarning(xmlFile, "Missing startNode for local power take off '%s'", baseName)
491 return false
492 end
493
494 powerTakeOffLocal.endNode = xmlFile:getValue(baseName.."#endNode", nil, self.components, self.i3dMappings)
495 if powerTakeOffLocal.endNode == nil then
496 Logging.xmlWarning(xmlFile, "Missing endNode for local power take off '%s'", baseName)
497 return false
498 end
499
500 powerTakeOffLocal.color = xmlFile:getValue(baseName .. "#color", nil, true)
501 powerTakeOffLocal.decalColor = xmlFile:getValue(baseName .. "#decalColor", nil, true)
502
503 local filename = xmlFile:getValue(baseName.. "#filename", "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
504 if filename ~= nil then
505 self:loadPowerTakeOffFromConfigFile(powerTakeOffLocal, filename)
506 end
507
508 return true
509end

loadOutputPowerTakeOff

Description
Definition
loadOutputPowerTakeOff()
Code
402function PowerTakeOffs:loadOutputPowerTakeOff(xmlFile, baseName, powerTakeOffOutput)
403 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseName .. "#linkNode", baseName .."#outputNode") -- FS19 to FS19
404 XMLUtil.checkDeprecatedXMLElements(xmlFile, baseName .. "#filename", "pto file is now defined in the pto input node") -- FS19 to FS19
405
406 powerTakeOffOutput.skipToInputAttacherIndex = xmlFile:getValue(baseName.. "#skipToInputAttacherIndex")
407
408 local outputNode = xmlFile:getValue(baseName.. "#outputNode", nil, self.components, self.i3dMappings)
409 if outputNode == nil and powerTakeOffOutput.skipToInputAttacherIndex == nil then
410 Logging.xmlWarning(xmlFile, "Pto output needs to have either a valid 'outputNode' or a 'skipToInputAttacherIndex' in '%s'", baseName)
411 return false
412 end
413
414 local attacherJointIndices = {}
415 local attacherJointIndicesRaw = xmlFile:getValue(baseName .. "#attacherJointIndices", nil, true)
416
417 if attacherJointIndicesRaw == nil then
418 Logging.xmlWarning(xmlFile, "Pto output needs to have valid 'attacherJointIndices' in '%s'", baseName)
419 return false
420 else
421 for _, index in ipairs(attacherJointIndicesRaw) do
422 attacherJointIndices[index] = true
423 end
424 end
425
426 powerTakeOffOutput.outputNode = outputNode
427 powerTakeOffOutput.attacherJointIndices = attacherJointIndices
428 powerTakeOffOutput.connectedInput = nil
429
430 powerTakeOffOutput.ptoName = xmlFile:getValue(baseName .. "#ptoName", "DEFAULT_PTO")
431
432 powerTakeOffOutput.objectChanges = {}
433 ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, baseName, powerTakeOffOutput.objectChanges, self.components, self)
434 ObjectChangeUtil.setObjectChanges(powerTakeOffOutput.objectChanges, false)
435
436 return true
437end

loadPowerTakeOffFromConfigFile

Description
Definition
loadPowerTakeOffFromConfigFile()
Code
770function PowerTakeOffs:loadPowerTakeOffFromConfigFile(powerTakeOff, xmlFilename)
771 xmlFilename = Utils.getFilename(xmlFilename, self.baseDirectory)
772 local xmlFile = XMLFile.load("PtoConfig", xmlFilename, PowerTakeOffs.xmlSchema)
773 if xmlFile ~= nil then
774 local i3dFilename = xmlFile:getValue("powerTakeOff#filename")
775 if i3dFilename ~= nil then
776 i3dFilename = Utils.getFilename(i3dFilename, self.baseDirectory)
777 powerTakeOff.xmlFile = xmlFile
778 local arguments = {
779 xmlFile = xmlFile,
780 powerTakeOff = powerTakeOff
781 }
782 powerTakeOff.sharedLoadRequestId = self:loadSubSharedI3DFile(i3dFilename, false, false, self.onPowerTakeOffI3DLoaded, self, arguments)
783 else
784 Logging.xmlWarning(self.xmlFile, "Failed to open powerTakeOff i3d file '%s' in '%s'", i3dFilename, xmlFilename)
785 xmlFile:delete()
786 end
787 else
788 Logging.warning("Failed to open powerTakeOff config file '%s'", xmlFilename)
789 end
790end

loadPowerTakeOffsFromXML

Description
Definition
loadPowerTakeOffsFromXML()
Code
371function PowerTakeOffs:loadPowerTakeOffsFromXML(xmlFile, key)
372 local spec = self.spec_powerTakeOffs
373
374 if SpecializationUtil.hasSpecialization(AttacherJoints, self.specializations) then
375 xmlFile:iterate(key..".output", function (_, outputKey)
376 local powerTakeOffOutput = {}
377 if self:loadOutputPowerTakeOff(xmlFile, outputKey, powerTakeOffOutput) then
378 table.insert(spec.outputPowerTakeOffs, powerTakeOffOutput)
379 end
380 end)
381 end
382
383 if SpecializationUtil.hasSpecialization(Attachable, self.specializations) then
384 xmlFile:iterate(key..".input", function (_, inputKey)
385 local powerTakeOffInput = {}
386 if self:loadInputPowerTakeOff(xmlFile, inputKey, powerTakeOffInput) then
387 table.insert(spec.inputPowerTakeOffs, powerTakeOffInput)
388 end
389 end)
390 end
391
392 xmlFile:iterate(key..".local", function (_, localKey)
393 local powerTakeOffLocal = {}
394 if self:loadLocalPowerTakeOff(xmlFile, localKey, powerTakeOffLocal) then
395 table.insert(spec.localPowerTakeOffs, powerTakeOffLocal)
396 end
397 end)
398end

loadSingleJointPowerTakeOff

Description
Definition
loadSingleJointPowerTakeOff()
Code
854function PowerTakeOffs:loadSingleJointPowerTakeOff(powerTakeOff, xmlFile, rootNode)
855 powerTakeOff.startJoint = xmlFile:getValue("powerTakeOff.startJoint#node", nil, rootNode)
856
857 powerTakeOff.scalePart = xmlFile:getValue("powerTakeOff.scalePart#node", nil, rootNode)
858 powerTakeOff.scalePartRef = xmlFile:getValue("powerTakeOff.scalePart#referenceNode", nil, rootNode)
859 local _, _, dis = localToLocal(powerTakeOff.scalePartRef, powerTakeOff.scalePart, 0, 0, 0)
860 powerTakeOff.scalePartBaseDistance = dis
861
862 powerTakeOff.translationPart = xmlFile:getValue("powerTakeOff.translationPart#node", nil, rootNode)
863 powerTakeOff.translationPartRef = xmlFile:getValue("powerTakeOff.translationPart#referenceNode", nil, rootNode)
864 powerTakeOff.translationPartLength = xmlFile:getValue("powerTakeOff.translationPart#length", 0.4)
865
866 powerTakeOff.decal = xmlFile:getValue("powerTakeOff.translationPart.decal#node", nil, rootNode)
867 powerTakeOff.decalSize = xmlFile:getValue("powerTakeOff.translationPart.decal#size", 0.1)
868 powerTakeOff.decalOffset = xmlFile:getValue("powerTakeOff.translationPart.decal#offset", 0.05)
869 powerTakeOff.decalMinOffset = xmlFile:getValue("powerTakeOff.translationPart.decal#minOffset", 0.01)
870
871 powerTakeOff.endJoint = xmlFile:getValue("powerTakeOff.endJoint#node", nil, rootNode)
872 powerTakeOff.linkNode = xmlFile:getValue("powerTakeOff.linkNode#node", nil, rootNode)
873
874 local _, _, betweenLength = localToLocal(powerTakeOff.translationPart, powerTakeOff.translationPartRef, 0, 0, 0)
875 local _, _, ptoLength = localToLocal(powerTakeOff.startNode, powerTakeOff.linkNode, 0, 0, 0)
876 powerTakeOff.betweenLength = math.abs(betweenLength)
877 powerTakeOff.connectorLength = math.abs(ptoLength) - math.abs(betweenLength)
878
879 setTranslation(powerTakeOff.linkNode, 0, 0, 0)
880 setRotation(powerTakeOff.linkNode, 0, 0, 0)
881
882 powerTakeOff.updateFunc = PowerTakeOffs.updateSingleJointPowerTakeOff
883 powerTakeOff.updateDistanceFunc = PowerTakeOffs.updateDistanceOfTypedPowerTakeOff
884 powerTakeOff.attachFunc = PowerTakeOffs.attachTypedPowerTakeOff
885 powerTakeOff.detachFunc = PowerTakeOffs.detachTypedPowerTakeOff
886end

onDelete

Description
Definition
onDelete()
Code
258function PowerTakeOffs:onDelete()
259 local spec = self.spec_powerTakeOffs
260 if spec.outputPowerTakeOffs ~= nil then
261 for _,output in pairs(spec.outputPowerTakeOffs) do
262 if output.xmlFile ~= nil then
263 output.xmlFile:delete()
264 output.xmlFile = nil
265 end
266 if output.sharedLoadRequestId ~= nil then
267 g_i3DManager:releaseSharedI3DFile(output.sharedLoadRequestId)
268 output.sharedLoadRequestId = nil
269 end
270
271 if output.rootNode ~= nil then
272 delete(output.rootNode)
273 delete(output.attachNode)
274 end
275 end
276 end
277
278 if spec.inputPowerTakeOffs ~= nil then
279 for _,input in pairs(spec.inputPowerTakeOffs) do
280 if input.xmlFile ~= nil then
281 input.xmlFile:delete()
282 input.xmlFile = nil
283 end
284 if input.sharedLoadRequestId ~= nil then
285 g_i3DManager:releaseSharedI3DFile(input.sharedLoadRequestId)
286 input.sharedLoadRequestId = nil
287 end
288 if input.rootNode ~= nil then
289 delete(input.rootNode)
290 delete(input.attachNode)
291 end
292 g_animationManager:deleteAnimations(input.animationNodes)
293 end
294 end
295
296 if spec.localPowerTakeOffs ~= nil then
297 for _,localPto in pairs(spec.localPowerTakeOffs) do
298 if localPto.xmlFile ~= nil then
299 localPto.xmlFile:delete()
300 localPto.xmlFile = nil
301 end
302 if localPto.sharedLoadRequestId ~= nil then
303 g_i3DManager:releaseSharedI3DFile(localPto.sharedLoadRequestId)
304 localPto.sharedLoadRequestId = nil
305 end
306 g_animationManager:deleteAnimations(localPto.animationNodes)
307 end
308 end
309end

onLoad

Description
Definition
onLoad()
Code
197function PowerTakeOffs:onLoad(savegame)
198 local spec = self.spec_powerTakeOffs
199
200 local configKey = string.format("vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration(%d)", spec.configIndex - 1)
201 ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.powerTakeOffs.powerTakeOffConfigurations.powerTakeOffConfiguration", spec.configIndex, self.components, self)
202
203 spec.outputPowerTakeOffs = {}
204 spec.inputPowerTakeOffs = {}
205 spec.localPowerTakeOffs = {}
206
207 self:loadPowerTakeOffsFromXML(self.xmlFile, "vehicle.powerTakeOffs")
208
209 if self.xmlFile:hasProperty(configKey) then
210 self:loadPowerTakeOffsFromXML(self.xmlFile, configKey)
211 end
212
213 spec.ignoreInvalidJointIndices = self.xmlFile:getValue("vehicle.powerTakeOffs#ignoreInvalidJointIndices", false)
214 spec.maxUpdateDistance = self.xmlFile:getValue("vehicle.powerTakeOffs#maxUpdateDistance", PowerTakeOffs.DEFAULT_MAX_UPDATE_DISTANCE)
215 spec.delayedPowerTakeOffsMountings = {}
216
217 if not self.isClient then
218 SpecializationUtil.removeEventListener(self, "onPostUpdate", PowerTakeOffs)
219 end
220end

onPostAttachImplement

Description
Definition
onPostAttachImplement()
Code
742function PowerTakeOffs:onPostAttachImplement(attachableObject, inputJointDescIndex, jointDescIndex)
743 local spec = self.spec_powerTakeOffs
744 for i=#spec.delayedPowerTakeOffsMountings, 1, -1 do
745 local delayedMounting = spec.delayedPowerTakeOffsMountings[i]
746 if delayedMounting.jointDescIndex == jointDescIndex then
747 local input = delayedMounting.input
748 local output = delayedMounting.output
749
750 if input.attachFunc ~= nil then
751 input.attachFunc(self, input, output)
752 end
753
754 ObjectChangeUtil.setObjectChanges(input.objectChanges, true)
755 ObjectChangeUtil.setObjectChanges(output.objectChanges, true)
756
757 table.remove(spec.delayedPowerTakeOffsMountings, i)
758 end
759 end
760end

onPostLoad

Description
Definition
onPostLoad()
Code
224function PowerTakeOffs:onPostLoad(savegame)
225 local spec = self.spec_powerTakeOffs
226
227 for i=1, #spec.outputPowerTakeOffs do
228 local powerTakeOffOutput = spec.outputPowerTakeOffs[i]
229
230 for index, _ in pairs(powerTakeOffOutput.attacherJointIndices) do
231 if self:getAttacherJointByJointDescIndex(index) == nil then
232 if not spec.ignoreInvalidJointIndices then
233 Logging.xmlWarning(self.xmlFile, "The given attacherJointIndex '%d' for powerTakeOff output '%s' can't be resolved into a valid attacherJoint", index, i)
234 end
235
236 powerTakeOffOutput.attacherJointIndices[index] = false
237 end
238 end
239 end
240
241 for i=1, #spec.inputPowerTakeOffs do
242 local inputPowerTakeOff = spec.inputPowerTakeOffs[i]
243
244 for index, _ in pairs(inputPowerTakeOff.inputAttacherJointIndices) do
245 if self:getInputAttacherJointByJointDescIndex(index) == nil then
246 if not spec.ignoreInvalidJointIndices then
247 Logging.xmlWarning(self.xmlFile, "The given inputAttacherJointIndex '%d' for powerTakeOff input '%s' can't be resolved into a valid attacherJoint", index, i)
248 end
249
250 inputPowerTakeOff.inputAttacherJointIndices[index] = false
251 end
252 end
253 end
254end

onPostUpdate

Description
Definition
onPostUpdate()
Code
313function PowerTakeOffs:onPostUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
314 if self.isClient then
315 local spec = self.spec_powerTakeOffs
316 if self.currentUpdateDistance < spec.maxUpdateDistance then
317 for i=1, #spec.inputPowerTakeOffs do
318 local input = spec.inputPowerTakeOffs[i]
319 if input.connectedVehicle ~= nil then
320 if self.updateLoopIndex == input.connectedVehicle.updateLoopIndex then
321 self:updatePowerTakeOff(input, dt)
322 end
323 end
324 end
325
326 if self.getAttachedImplements ~= nil then
327 local impements = self:getAttachedImplements()
328 for i=1, #impements do
329 local object = impements[i].object
330 if object.updateAttachedPowerTakeOffs ~= nil then
331 object:updateAttachedPowerTakeOffs(dt, self)
332 end
333 end
334 end
335
336 local isPowerTakeOffActive = self:getIsPowerTakeOffActive()
337 if spec.lastIsPowerTakeOffActive ~= isPowerTakeOffActive then
338 for i=1, #spec.inputPowerTakeOffs do
339 local input = spec.inputPowerTakeOffs[i]
340 if isPowerTakeOffActive and input.connectedVehicle ~= nil then
341 g_animationManager:startAnimations(input.animationNodes)
342 else
343 g_animationManager:stopAnimations(input.animationNodes)
344 end
345 end
346
347 for i=1, #spec.localPowerTakeOffs do
348 local localPto = spec.localPowerTakeOffs[i]
349 if isPowerTakeOffActive then
350 g_animationManager:startAnimations(localPto.animationNodes)
351 else
352 g_animationManager:stopAnimations(localPto.animationNodes)
353 end
354 end
355
356 spec.lastIsPowerTakeOffActive = isPowerTakeOffActive
357 end
358 end
359 end
360end

onPowerTakeOffI3DLoaded

Description
Definition
onPowerTakeOffI3DLoaded()
Code
794function PowerTakeOffs:onPowerTakeOffI3DLoaded(i3dNode, failedReason, args)
795 local xmlFile = args.xmlFile
796 local powerTakeOff = args.powerTakeOff
797
798 if i3dNode ~= 0 then
799 powerTakeOff.startNode = xmlFile:getValue("powerTakeOff.startNode#node", nil, i3dNode)
800 powerTakeOff.size = xmlFile:getValue("powerTakeOff#size", 0.19)
801 powerTakeOff.minLength = xmlFile:getValue("powerTakeOff#minLength", 0.6)
802 powerTakeOff.maxAngle = xmlFile:getValue("powerTakeOff#maxAngle", 45)
803 powerTakeOff.zOffset = xmlFile:getValue("powerTakeOff#zOffset", 0)
804
805 powerTakeOff.animationNodes = g_animationManager:loadAnimations(xmlFile, "powerTakeOff.animationNodes", i3dNode, self)
806
807 if xmlFile:getValue("powerTakeOff#isSingleJoint") then
808 self:loadSingleJointPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
809 elseif xmlFile:getValue("powerTakeOff#isDoubleJoint") then
810 self:loadDoubleJointPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
811 else
812 self:loadBasicPowerTakeOff(powerTakeOff, xmlFile, i3dNode)
813 end
814
815 if powerTakeOff.color ~= nil and #powerTakeOff.color >= 3 then
816 local colorShaderParameter = xmlFile:getValue("powerTakeOff#colorShaderParameter")
817 if colorShaderParameter ~= nil then
818 I3DUtil.setShaderParameterRec(powerTakeOff.startNode, colorShaderParameter, powerTakeOff.color[1], powerTakeOff.color[2], powerTakeOff.color[3])
819 end
820 end
821
822 if powerTakeOff.decalColor ~= nil and #powerTakeOff.decalColor >= 3 then
823 local decalColorShaderParameter = xmlFile:getValue("powerTakeOff#decalColorShaderParameter")
824 if decalColorShaderParameter ~= nil then
825 I3DUtil.setShaderParameterRec(powerTakeOff.startNode, decalColorShaderParameter, powerTakeOff.decalColor[1], powerTakeOff.decalColor[2], powerTakeOff.decalColor[3])
826 end
827 end
828
829 link(powerTakeOff.inputNode, powerTakeOff.startNode)
830
831 powerTakeOff.i3dLoaded = true
832
833 if powerTakeOff.isLocal then
834 self:placeLocalPowerTakeOff(powerTakeOff)
835 else
836 self:parkPowerTakeOff(powerTakeOff)
837 end
838
839 self:updatePowerTakeOff(powerTakeOff, 0)
840
841 delete(i3dNode)
842 else
843 if not (self.isDeleted or self.isDeleting) then
844 Logging.xmlWarning(self.xmlFile, "Failed to find powerTakeOff in i3d file '%s'", powerTakeOff.filename)
845 end
846 end
847
848 xmlFile:delete()
849 powerTakeOff.xmlFile = nil
850end

onPreAttachImplement

Description
Definition
onPreAttachImplement()
Code
736function PowerTakeOffs:onPreAttachImplement(attachableObject, inputJointDescIndex, jointDescIndex)
737 self:attachPowerTakeOff(attachableObject, inputJointDescIndex, jointDescIndex)
738end

onPreDetachImplement

Description
Definition
onPreDetachImplement()
Code
764function PowerTakeOffs:onPreDetachImplement(implement)
765 self:detachPowerTakeOff(self, implement)
766end

onPreLoad

Description
Definition
onPreLoad()
Code
190function PowerTakeOffs:onPreLoad(savegame)
191 local spec = self.spec_powerTakeOffs
192 spec.configIndex = self:getPowerTakeOffConfigIndex()
193end

parkPowerTakeOff

Description
Definition
parkPowerTakeOff()
Code
714function PowerTakeOffs:parkPowerTakeOff(input)
715 if input.detachNode ~= nil then
716 link(input.detachNode, input.linkNode)
717 link(input.inputNode, input.startNode)
718 self:updatePowerTakeOff(input, 0)
719 self:updatePowerTakeOffLength(input)
720 else
721 -- keep both inside of the vehicle
722 -- so other specializations can still keep track of them (e.g. washable)
723 link(input.inputNode, input.linkNode)
724 link(input.inputNode, input.startNode)
725
726 setVisibility(input.linkNode, false)
727 setVisibility(input.startNode, false)
728 end
729
730 setTranslation(input.linkNode, 0, 0, input.zOffset)
731 setTranslation(input.startNode, 0, 0, -input.zOffset)
732end

placeLocalPowerTakeOff

Description
Definition
placeLocalPowerTakeOff()
Code
513function PowerTakeOffs:placeLocalPowerTakeOff(powerTakeOff)
514 if powerTakeOff.i3dLoaded then
515 if not powerTakeOff.isPlaced then
516 link(powerTakeOff.endNode, powerTakeOff.linkNode)
517
518 setTranslation(powerTakeOff.linkNode, 0, 0, powerTakeOff.zOffset)
519 setTranslation(powerTakeOff.startNode, 0, 0, -powerTakeOff.zOffset)
520
521 self:updatePowerTakeOffLength(powerTakeOff)
522 powerTakeOff.isPlaced = true
523 end
524
525 self:updatePowerTakeOff(powerTakeOff, 0)
526 end
527end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
18function PowerTakeOffs.prerequisitesPresent(specializations)
19 return SpecializationUtil.hasSpecialization(AttacherJoints, specializations)
20 or SpecializationUtil.hasSpecialization(Attachable, specializations)
21end

registerEventListeners

Description
Definition
registerEventListeners()
Code
177function PowerTakeOffs.registerEventListeners(vehicleType)
178 SpecializationUtil.registerEventListener(vehicleType, "onPreLoad", PowerTakeOffs)
179 SpecializationUtil.registerEventListener(vehicleType, "onLoad", PowerTakeOffs)
180 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", PowerTakeOffs)
181 SpecializationUtil.registerEventListener(vehicleType, "onDelete", PowerTakeOffs)
182 SpecializationUtil.registerEventListener(vehicleType, "onPostUpdate", PowerTakeOffs)
183 SpecializationUtil.registerEventListener(vehicleType, "onPreAttachImplement", PowerTakeOffs)
184 SpecializationUtil.registerEventListener(vehicleType, "onPostAttachImplement", PowerTakeOffs)
185 SpecializationUtil.registerEventListener(vehicleType, "onPreDetachImplement", PowerTakeOffs)
186end

registerFunctions

Description
Definition
registerFunctions()
Code
131function PowerTakeOffs.registerFunctions(vehicleType)
132 SpecializationUtil.registerFunction(vehicleType, "getPowerTakeOffConfigIndex", PowerTakeOffs.getPowerTakeOffConfigIndex)
133 SpecializationUtil.registerFunction(vehicleType, "loadPowerTakeOffsFromXML", PowerTakeOffs.loadPowerTakeOffsFromXML)
134 SpecializationUtil.registerFunction(vehicleType, "loadOutputPowerTakeOff", PowerTakeOffs.loadOutputPowerTakeOff)
135 SpecializationUtil.registerFunction(vehicleType, "loadInputPowerTakeOff", PowerTakeOffs.loadInputPowerTakeOff)
136 SpecializationUtil.registerFunction(vehicleType, "loadLocalPowerTakeOff", PowerTakeOffs.loadLocalPowerTakeOff)
137 SpecializationUtil.registerFunction(vehicleType, "placeLocalPowerTakeOff", PowerTakeOffs.placeLocalPowerTakeOff)
138 SpecializationUtil.registerFunction(vehicleType, "updatePowerTakeOff", PowerTakeOffs.updatePowerTakeOff)
139 SpecializationUtil.registerFunction(vehicleType, "updateAttachedPowerTakeOffs", PowerTakeOffs.updateAttachedPowerTakeOffs)
140 SpecializationUtil.registerFunction(vehicleType, "updatePowerTakeOffLength", PowerTakeOffs.updatePowerTakeOffLength)
141 SpecializationUtil.registerFunction(vehicleType, "getOutputPowerTakeOffsByJointDescIndex", PowerTakeOffs.getOutputPowerTakeOffsByJointDescIndex)
142 SpecializationUtil.registerFunction(vehicleType, "getOutputPowerTakeOffs", PowerTakeOffs.getOutputPowerTakeOffs)
143 SpecializationUtil.registerFunction(vehicleType, "getInputPowerTakeOffs", PowerTakeOffs.getInputPowerTakeOffs)
144 SpecializationUtil.registerFunction(vehicleType, "getInputPowerTakeOffsByJointDescIndexAndName", PowerTakeOffs.getInputPowerTakeOffsByJointDescIndexAndName)
145 SpecializationUtil.registerFunction(vehicleType, "getIsPowerTakeOffActive", PowerTakeOffs.getIsPowerTakeOffActive)
146 SpecializationUtil.registerFunction(vehicleType, "attachPowerTakeOff", PowerTakeOffs.attachPowerTakeOff)
147 SpecializationUtil.registerFunction(vehicleType, "detachPowerTakeOff", PowerTakeOffs.detachPowerTakeOff)
148 SpecializationUtil.registerFunction(vehicleType, "checkPowerTakeOffCollision", PowerTakeOffs.checkPowerTakeOffCollision)
149 SpecializationUtil.registerFunction(vehicleType, "parkPowerTakeOff", PowerTakeOffs.parkPowerTakeOff)
150
151 SpecializationUtil.registerFunction(vehicleType, "loadPowerTakeOffFromConfigFile", PowerTakeOffs.loadPowerTakeOffFromConfigFile)
152 SpecializationUtil.registerFunction(vehicleType, "onPowerTakeOffI3DLoaded", PowerTakeOffs.onPowerTakeOffI3DLoaded)
153
154 SpecializationUtil.registerFunction(vehicleType, "loadSingleJointPowerTakeOff", PowerTakeOffs.loadSingleJointPowerTakeOff)
155 SpecializationUtil.registerFunction(vehicleType, "updateSingleJointPowerTakeOff", PowerTakeOffs.updateSingleJointPowerTakeOff)
156
157 SpecializationUtil.registerFunction(vehicleType, "loadDoubleJointPowerTakeOff", PowerTakeOffs.loadDoubleJointPowerTakeOff)
158 SpecializationUtil.registerFunction(vehicleType, "updateDoubleJointPowerTakeOff", PowerTakeOffs.updateDoubleJointPowerTakeOff)
159
160 SpecializationUtil.registerFunction(vehicleType, "loadBasicPowerTakeOff", PowerTakeOffs.loadBasicPowerTakeOff)
161
162 SpecializationUtil.registerFunction(vehicleType, "attachTypedPowerTakeOff", PowerTakeOffs.attachTypedPowerTakeOff)
163 SpecializationUtil.registerFunction(vehicleType, "detachTypedPowerTakeOff", PowerTakeOffs.detachTypedPowerTakeOff)
164
165 SpecializationUtil.registerFunction(vehicleType, "validatePowerTakeOffAttachment", PowerTakeOffs.validatePowerTakeOffAttachment)
166end

registerInputXMLPaths

Description
Definition
registerInputXMLPaths()
Code
105function PowerTakeOffs.registerInputXMLPaths(schema, basePath)
106 schema:register(XMLValueType.NODE_INDEX, basePath .. "#inputNode", "Input node")
107 schema:register(XMLValueType.VECTOR_N, basePath .. "#inputAttacherJointIndices", "Input attacher joint indices")
108 schema:register(XMLValueType.NODE_INDEX, basePath .. "#detachNode", "Detach node")
109 schema:register(XMLValueType.BOOL, basePath .. "#aboveAttacher", "Above attacher", true)
110 schema:register(XMLValueType.COLOR, basePath .. "#color", "Color")
111 schema:register(XMLValueType.COLOR, basePath .. "#decalColor", "Color of decals")
112 schema:register(XMLValueType.STRING, basePath .. "#filename", "Path to pto xml file", "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
113 schema:register(XMLValueType.STRING, basePath .. "#ptoName", "Pto name", "DEFAULT_PTO")
114
115 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
116end

registerLocalXMLPaths

Description
Definition
registerLocalXMLPaths()
Code
120function PowerTakeOffs.registerLocalXMLPaths(schema, basePath)
121 schema:register(XMLValueType.NODE_INDEX, basePath .. "#startNode", "Start node")
122 schema:register(XMLValueType.NODE_INDEX, basePath .. "#endNode", "End node")
123 schema:register(XMLValueType.COLOR, basePath .. "#color", "Color")
124 schema:register(XMLValueType.COLOR, basePath .. "#decalColor", "Color of decals")
125 schema:register(XMLValueType.STRING, basePath .. "#filename", "Path to pto xml file", "$data/shared/assets/powerTakeOffs/walterscheidW.xml")
126end

registerOutputXMLPaths

Description
Definition
registerOutputXMLPaths()
Code
94function PowerTakeOffs.registerOutputXMLPaths(schema, basePath)
95 schema:register(XMLValueType.INT, basePath .. "#skipToInputAttacherIndex", "Skip to input attacher joint index")
96 schema:register(XMLValueType.NODE_INDEX, basePath .. "#outputNode", "Output node")
97 schema:register(XMLValueType.VECTOR_N, basePath .. "#attacherJointIndices", "Attacher joint indices")
98 schema:register(XMLValueType.STRING, basePath .. "#ptoName", "Output name", "DEFAULT_PTO")
99
100 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath)
101end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
170function PowerTakeOffs.registerOverwrittenFunctions(vehicleType)
171 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadExtraDependentParts", PowerTakeOffs.loadExtraDependentParts)
172 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateExtraDependentParts", PowerTakeOffs.updateExtraDependentParts)
173end

registerXMLPaths

Description
Definition
registerXMLPaths()
Code
86function PowerTakeOffs.registerXMLPaths(schema, basePath)
87 PowerTakeOffs.registerOutputXMLPaths(schema, basePath .. ".output(?)")
88 PowerTakeOffs.registerInputXMLPaths(schema, basePath .. ".input(?)")
89 PowerTakeOffs.registerLocalXMLPaths(schema, basePath .. ".local(?)")
90end

updateAttachedPowerTakeOffs

Description
Definition
updateAttachedPowerTakeOffs()
Code
541function PowerTakeOffs:updateAttachedPowerTakeOffs(dt, attacherVehicle)
542 local spec = self.spec_powerTakeOffs
543 for _, input in pairs(spec.inputPowerTakeOffs) do
544 if input.connectedVehicle ~= nil then
545 if input.connectedVehicle == attacherVehicle then
546 if self.updateLoopIndex == input.connectedVehicle.updateLoopIndex then
547 self:updatePowerTakeOff(input, dt)
548 end
549 end
550 end
551 end
552end

updateDistanceOfTypedPowerTakeOff

Description
Definition
updateDistanceOfTypedPowerTakeOff()
Code
977function PowerTakeOffs:updateDistanceOfTypedPowerTakeOff(powerTakeOff)
978 local attachLength = calcDistanceFrom(powerTakeOff.linkNode, powerTakeOff.startNode)
979 local transPartScale = math.max(attachLength - powerTakeOff.connectorLength, 0) / powerTakeOff.betweenLength
980 setScale(powerTakeOff.translationPart, 1, 1, transPartScale)
981
982 if powerTakeOff.decal ~= nil then
983 local transPartLength = transPartScale * powerTakeOff.translationPartLength
984
985 if transPartLength > powerTakeOff.decalMinOffset * 2 + powerTakeOff.decalSize then
986 local offset = math.min((transPartLength - powerTakeOff.decalSize) / 2, powerTakeOff.decalOffset)
987 local decalTranslation = offset + powerTakeOff.decalSize * 0.5
988 local x, y, _ = getTranslation(powerTakeOff.decal)
989 setTranslation(powerTakeOff.decal, x, y, -decalTranslation/transPartScale)
990 setScale(powerTakeOff.decal, 1, 1, 1/transPartScale)
991 else
992 setVisibility(powerTakeOff.decal, false)
993 end
994 end
995end

updateDoubleJointPowerTakeOff

Description
Definition
updateDoubleJointPowerTakeOff()
Code
945function PowerTakeOffs:updateDoubleJointPowerTakeOff(powerTakeOff, dt)
946 local x, y, z = getWorldTranslation(powerTakeOff.startNode)
947 local dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint2), x, y, z)
948 I3DUtil.setDirection(powerTakeOff.endJoint2, dx*0.5, dy*0.5, dz, 0, 1, 0)
949
950 x, y, z = getWorldTranslation(powerTakeOff.endJoint1Ref)
951 dx, dy, dz = worldToLocal(getParent(powerTakeOff.startJoint1), x, y, z)
952 I3DUtil.setDirection(powerTakeOff.startJoint1, dx*0.5, dy*0.5, dz, 0, 1, 0)
953
954 x, y, z = getWorldTranslation(powerTakeOff.endJoint1Ref)
955 dx, dy, dz = worldToLocal(getParent(powerTakeOff.startJoint2), x, y, z)
956 I3DUtil.setDirection(powerTakeOff.startJoint2, dx, dy, dz, 0, 1, 0)
957
958 dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint1), x, y, z)
959 setTranslation(powerTakeOff.endJoint1, 0, 0, MathUtil.vector3Length(dx, dy, dz))
960
961 local dist = calcDistanceFrom(powerTakeOff.scalePart, powerTakeOff.scalePartRef)
962 setScale(powerTakeOff.scalePart, 1, 1, dist / powerTakeOff.scalePartBaseDistance)
963end

updateExtraDependentParts

Description
Definition
updateExtraDependentParts()
Code
1075function PowerTakeOffs:updateExtraDependentParts(superFunc, part, dt)
1076 superFunc(self, part, dt)
1077
1078 if part.powerTakeOffs ~= nil then
1079 local spec = self.spec_powerTakeOffs
1080 for i, index in ipairs(part.powerTakeOffs) do
1081 if spec.inputPowerTakeOffs[index] == nil then
1082 part.powerTakeOffs[i] = nil
1083 Logging.xmlWarning(self.xmlFile, "Unable to find powerTakeOff index '%d' for movingPart/movingTool '%s'", index, getName(part.node))
1084 else
1085 self:updatePowerTakeOff(spec.inputPowerTakeOffs[index], dt)
1086 end
1087 end
1088 end
1089
1090 if part.localPowerTakeOffs ~= nil then
1091 local spec = self.spec_powerTakeOffs
1092 for i, index in ipairs(part.localPowerTakeOffs) do
1093 if spec.localPowerTakeOffs[index] == nil then
1094 part.localPowerTakeOffs[i] = nil
1095 Logging.xmlWarning(self.xmlFile, "Unable to find local powerTakeOff index '%d' for movingPart/movingTool '%s'", index, getName(part.node))
1096 else
1097 self:placeLocalPowerTakeOff(spec.localPowerTakeOffs[index], dt)
1098 end
1099 end
1100 end
1101end

updatePowerTakeOff

Description
Definition
updatePowerTakeOff()
Code
531function PowerTakeOffs:updatePowerTakeOff(input, dt)
532 if input.i3dLoaded then
533 if input.updateFunc ~= nil then
534 input.updateFunc(self, input, dt)
535 end
536 end
537end

updatePowerTakeOffLength

Description
Definition
updatePowerTakeOffLength()
Code
556function PowerTakeOffs:updatePowerTakeOffLength(input)
557 if input.i3dLoaded then
558 if input.updateDistanceFunc ~= nil then
559 input.updateDistanceFunc(self, input)
560 end
561 end
562end

updateSingleJointPowerTakeOff

Description
Definition
updateSingleJointPowerTakeOff()
Code
890function PowerTakeOffs:updateSingleJointPowerTakeOff(powerTakeOff, dt)
891 local x, y, z = getWorldTranslation(powerTakeOff.linkNode)
892
893 local dx, dy, dz = worldToLocal(powerTakeOff.startNode, x, y, z)
894 I3DUtil.setDirection(powerTakeOff.startJoint, dx, dy, dz, 0, 1, 0)
895
896 dx, dy, dz = worldToLocal(getParent(powerTakeOff.endJoint), x, y, z)
897 setTranslation(powerTakeOff.endJoint, 0, 0, MathUtil.vector3Length(dx, dy, dz))
898
899 local dist = calcDistanceFrom(powerTakeOff.scalePart, powerTakeOff.scalePartRef)
900 setScale(powerTakeOff.scalePart, 1, 1, dist / powerTakeOff.scalePartBaseDistance)
901end

validatePowerTakeOffAttachment

Description
Definition
validatePowerTakeOffAttachment()
Code
1023function PowerTakeOffs:validatePowerTakeOffAttachment(powerTakeOff, output)
1024 if output.outputNode == nil or powerTakeOff.inputNode == nil then
1025 return false
1026 end
1027
1028 local x1, y1, z1 = getWorldTranslation(output.outputNode)
1029 local x2, y2, z2 = getWorldTranslation(powerTakeOff.inputNode)
1030
1031 local length = MathUtil.vector3Length(x1-x2, y1-y2, z1-z2)
1032 if length < powerTakeOff.minLength then
1033 return false
1034 end
1035
1036 local length2D = MathUtil.vector2Length(x1-x2, z1-z2)
1037 local angle = math.acos(length2D / length)
1038 if angle > powerTakeOff.maxAngle then
1039 return false
1040 end
1041
1042 return true
1043end