def getReflectVector(self, vector, planeCoords, collisionWeight):

        vectorReset = [
            planeCoords[0][0] * -1, planeCoords[0][1] * -1,
            planeCoords[0][2] * -1
        ]

        for i in range(0, 3):
            for j in range(0, 3):
                planeCoords[i][j] += vectorReset[j]

        trsObj = trsClass.trsClass()
        trsObj.value = vector + [0, 0, 0, 1, 1, 1]
        trsObj.mirror(planeCoords)

        trsObj * collisionWeight

        reflectVector = trsObj.value[0:3]

        return reflectVector
    def getlimiteTranslateValue(self, axeDir, limiteRotValues, origTrsWorld,
                                targetTrs):

        # axe dir
        signDir = 1
        if (2 < axeDir):
            signDir = -1
            axeDir -= 3

        # axe dir

        trsObj = trsClass.trsClass()
        distance = trsObj.toDistance(targetTrs, inTrsValue=origTrsWorld)

        # CONVERT TO ROT LIMIT
        limitRot = []
        for i in range(0, 3):
            rotationValue = [0, 0, 0]
            rotationValue[i] = limiteRotValues[i]
            limitRot.append(rotationValue)

        # CONVERT ROT TO TRANSLATE LIMIT
        axeLimites = [0, 2, 1]

        limitCoords = [0, 0, 0]
        offsetTrsRotate = [0, 0, 0, 0, 0, 0, 1, 1, 1]
        offsetTrsTranslate = [0, 0, 0, 0, 0, 0, 1, 1, 1]
        offsetTrsTranslate[axeDir] = distance * signDir

        for i in range(0, 3):
            offsetTrsRotate[3:6] = limitRot[i]
            trsObj.offsetItself(offsetTrsRotate, inTrsValue=origTrsWorld)
            trsObj.offsetItself(offsetTrsTranslate)
            limitCoords[i] = (trsObj.value[0:3])

        return limitCoords
    def compute(self, plug, dataBlock):

        outsAttr = [self.outputTAttr, self.outputRAttr]
        if not (plug in outsAttr):
            return om.kUnknownParameter

    #_____________________________________________________________________________________ IN

        dataHandle = dataBlock.inputValue(self.input0Attr)
        activate = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input1Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrixA = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input2Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrixB = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input3Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrixC = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input4Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrixD = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input5Attr)
        inMFloatMatrix = dataHandle.asFloatMatrix()
        fatherMatrix = MMatrixToNum(inMFloatMatrix)

        #_____________________________________________________________________________________COMPUTE
        '''
        par convention on va dire que les points ABCD sont repartis de cette maniere:
        AB
        DC  ( vue de haut )
        avec AB devant CD derriere et qui se lit dans le sens des aiguille d'une montre
        
        '''

        trsObj = trsClass.trsClass()

        #_______________ TRS
        initTrsWorldA = trsObj.createFromFloatMatrix(worldMatrixA)
        initTrsWorldB = trsObj.createFromFloatMatrix(worldMatrixB)
        initTrsWorldC = trsObj.createFromFloatMatrix(worldMatrixC)
        initTrsWorldD = trsObj.createFromFloatMatrix(worldMatrixD)
        fatherTrs = trsObj.createFromFloatMatrix(fatherMatrix)

        #_______________ POSITION

        outPosition = [0, 0, 0]

        outPosition[0] = (initTrsWorldA[0] + initTrsWorldB[0] +
                          initTrsWorldC[0] + initTrsWorldD[0]) / 4
        outPosition[1] = (initTrsWorldA[1] + initTrsWorldB[1] +
                          initTrsWorldC[1] + initTrsWorldD[1]) / 4
        outPosition[2] = (initTrsWorldA[2] + initTrsWorldB[2] +
                          initTrsWorldC[2] + initTrsWorldD[2]) / 4

        #_______________ ROTATION

        outRotation = [0, 0, 0]

        # vector corner A
        vUpCornerA = [0, 1, 0]
        vDirCornerA = [
            initTrsWorldA[0] - initTrsWorldD[0],
            initTrsWorldA[1] - initTrsWorldD[1],
            initTrsWorldA[2] - initTrsWorldD[2]
        ]
        vSideCornerA = [
            initTrsWorldB[0] - initTrsWorldA[0],
            initTrsWorldB[1] - initTrsWorldA[1],
            initTrsWorldB[2] - initTrsWorldA[2]
        ]

        # vector corner C
        vUpCornerC = [0, 1, 0]
        vDirCornerC = [
            initTrsWorldB[0] - initTrsWorldC[0],
            initTrsWorldB[1] - initTrsWorldC[1],
            initTrsWorldB[2] - initTrsWorldC[2]
        ]
        vSideCornerC = [
            initTrsWorldC[0] - initTrsWorldD[0],
            initTrsWorldC[1] - initTrsWorldD[1],
            initTrsWorldC[2] - initTrsWorldD[2]
        ]

        # moyenne
        vUpCorner = [(vUpCornerA[0] + vUpCornerC[0]) / 2,
                     (vUpCornerA[1] + vUpCornerC[1]) / 2,
                     (vUpCornerA[2] + vUpCornerC[2]) / 2]
        vDirCorner = [(vDirCornerA[0] + vDirCornerC[0]) / 2,
                      (vDirCornerA[1] + vDirCornerC[1]) / 2,
                      (vDirCornerA[2] + vDirCornerC[2]) / 2]
        vSideCorner = [(vSideCornerA[0] + vSideCornerC[0]) / 2,
                       (vSideCornerA[1] + vSideCornerC[1]) / 2,
                       (vSideCornerA[2] + vSideCornerC[2]) / 2]

        # convert to rotation
        trsObj.createFromTripleVectors(vDirCorner,
                                       vUpCorner,
                                       vSideCorner,
                                       accuracyOrder=[0, 2, 1])
        outRotation = trsObj[3:6]

        #_____________________________________________________________________________________ OUT NODE

        trsOut = outPosition + outRotation + [1, 1, 1]
        trsOutUnder = trsObj.parent(fatherTrs, inTrsValue=trsOut)

        dataHandle = dataBlock.outputValue(self.outputTAttr)
        dataHandle.set3Float(trsOutUnder[0], trsOutUnder[1], trsOutUnder[2])

        dataHandle = dataBlock.outputValue(self.outputRAttr)
        dataHandle.set3Float(trsOutUnder[3], trsOutUnder[4], trsOutUnder[5])

        dataBlock.setClean(plug)
    def compute(self, plug, dataBlock):

        outsAttr = [self.outputXAttr, self.outputYAttr, self.outputZAttr]
        if not (plug in outsAttr):
            return om.kUnknownParameter
    #_____________________________________________________________________________________ IN

        dataHandle = dataBlock.inputValue(self.inputTimeAttr)
        intime = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input1Attr)
        activate = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input2Attr)
        leadMFloatMatrix = dataHandle.asFloatMatrix()
        leadMatrix = MMatrixToNum(leadMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input3Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrix = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input4Attr)
        mass = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input5Attr)
        elasticity = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input6Attr)
        damping = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input7Attr)
        collision = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input8Attr)
        self.minRotValues = dataHandle.asFloat3()
        self.minRotValues = [
            self.minRotValues[0], self.minRotValues[1], self.minRotValues[2]
        ]

        dataHandle = dataBlock.inputValue(self.input9Attr)
        self.maxRotValues = dataHandle.asFloat3()
        self.maxRotValues = [
            self.maxRotValues[0], self.maxRotValues[1], self.maxRotValues[2]
        ]

        dataHandle = dataBlock.inputValue(self.input10Attr)
        distance = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input11Attr)
        self.nbrEval = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input12Attr)
        self.lastTime = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input13Attr)
        self.lastSpeed = dataHandle.asFloat3()
        self.lastSpeed = [
            self.lastSpeed[0], self.lastSpeed[1], self.lastSpeed[2]
        ]

        dataHandle = dataBlock.inputValue(self.input14Attr)
        self.slaveValue = dataHandle.asFloat3()
        self.slaveValue = [
            self.slaveValue[0], self.slaveValue[1], self.slaveValue[2]
        ]

        dataHandle = dataBlock.inputValue(self.input15Attr)
        axeDirWay = dataHandle.asInt()

        dataHandle = dataBlock.inputValue(self.input16Attr)
        ctrlTranslate = dataHandle.asFloat3()

        dataHandle = dataBlock.inputValue(self.input17Attr)
        ctrlRotate = dataHandle.asFloat3()

        dataHandle = dataBlock.inputValue(self.input18Attr)
        ctrlScale = dataHandle.asFloat3()

        dataHandle = dataBlock.inputValue(self.input19Attr)
        follow = dataHandle.asFloat()

        #_____________________________________________________________________________________COMPUTE
        trsObj = trsClass.trsClass()

        #_______________ SIGN AXE
        signDir = 1
        axeDir = axeDirWay
        if (2 < axeDir):
            signDir = -1
            axeDir -= 3

    #_______________ DELTA TIME
        incrEval = 0.04
        self.nbrEval += incrEval

        curTime = self.nbrEval
        deltaTime = curTime - self.lastTime
        self.lastTime = curTime

        #_______________ TRS
        origTrsWorld = trsObj.createFromFloatMatrix(worldMatrix)

        ctrlTrsLocal = [
            ctrlTranslate[0], ctrlTranslate[1], ctrlTranslate[2],
            ctrlRotate[0], ctrlRotate[1], ctrlRotate[2], ctrlScale[0],
            ctrlScale[1], ctrlScale[2]
        ]
        ctrlTrsWorld = trsObj.unParent(origTrsWorld, inTrsValue=ctrlTrsLocal)

        ctrlTrsLocalClamped = ctrlTrsLocal[:]
        if not (collision == 0):
            for i in range(0, 3):
                if not (i == axeDir):
                    ctrlTrsLocalClamped[i + 3] = max(
                        min(ctrlTrsLocal[i + 3], self.maxRotValues[i]),
                        self.minRotValues[i])

        ctrlTrsWorldClamped = trsObj.unParent(origTrsWorld,
                                              inTrsValue=ctrlTrsLocalClamped)

        offsetTrsBase = [0, 0, 0, 0, 0, 0, 1, 1, 1]
        offsetTrsBase[axeDir] = distance * signDir
        ctrlOffsetTrs = trsObj.offsetItself(offsetTrsBase,
                                            inTrsValue=ctrlTrsWorldClamped)

        #_______________ DYNAMIC
        curentFrame = mc.currentTime(query=True)
        startFrame = mc.playbackOptions(query=True, minTime=True)

        if (activate == 0) or (curentFrame == startFrame):

            self.nbrEval = 0
            self.lastTime = 0
            self.lastSpeed = [0, 0, 0]
            self.slaveValue = ctrlOffsetTrs[0:3]
            self.leadCollision = None
            angleOut = self.angleCompute(axeDirWay, ctrlTrsWorld,
                                         ctrlOffsetTrs, self.slaveValue)

        else:

            # DYNAMIC
            for i in range(0, 3):
                self.slaveValue[i], self.lastSpeed[i] = self.computeDynamic(
                    ctrlOffsetTrs[i], self.slaveValue[i], self.lastSpeed[i],
                    mass, elasticity, damping, deltaTime)

            # FOLLOW SYS
            if not (follow == 0):
                vToTarget = ompy.MVector(
                    self.slaveValue[0] - ctrlTrsWorldClamped[0],
                    self.slaveValue[1] - ctrlTrsWorldClamped[1],
                    self.slaveValue[2] - ctrlTrsWorldClamped[2])
                vFollow = vToTarget * (distance / vToTarget.length())
                self.slaveValue = [
                    ctrlTrsWorldClamped[0] + vFollow.x,
                    ctrlTrsWorldClamped[1] + vFollow.y,
                    ctrlTrsWorldClamped[2] + vFollow.z
                ]

            # COLLISION
            allAxesLimites = [[0, 2, 1], [2, 1, 0], [1, 0, 2]]
            axeLimites = allAxesLimites[axeDir]

            if not (collision == 0):

                ctrlTrsWorldOrigOrient = ctrlTrsWorld[0:3] + origTrsWorld[
                    3:6] + ctrlTrsWorld[6:9]
                origOffsetTrs = trsObj.offsetItself(
                    offsetTrsBase, inTrsValue=ctrlTrsWorldOrigOrient)
                angleOutCollision = self.angleCompute(
                    axeDirWay, ctrlTrsWorldOrigOrient, origOffsetTrs,
                    self.slaveValue + [0, 0, 0, 1, 1, 1])

                # RECOMPUTE NEXT DYN:   slaveValue   lastSpeed

                for i in range(0, 3):

                    if (i == axeDir):
                        continue

                    if (self.minRotValues[i] == 0) and (self.maxRotValues[i]
                                                        == 0):
                        planeCoords = trsObj.toPlaneCoords(
                            axeNormal=axeLimites[i],
                            inTrsValue=ctrlTrsWorldOrigOrient)
                        self.slaveValue = trsObj.snapOnPlane(
                            planeCoords,
                            inTrsValue=self.slaveValue + [0, 0, 0, 1, 1, 1])
                        continue

                    if (angleOutCollision[i] < self.minRotValues[i]) or (
                            self.maxRotValues[i] < angleOutCollision[i]):

                        if (angleOutCollision[i] < self.minRotValues[i]):
                            limitRotValue = self.minRotValues
                        elif (self.maxRotValues[i] < angleOutCollision[i]):
                            limitRotValue = self.maxRotValues

                        # plane coord corresponding to the limit

                        offsetTrsBase = [0, 0, 0, 0, 0, 0, 1, 1, 1]
                        offsetTrsBase[i + 3] = limitRotValue[i]
                        trsObj.offsetItself(offsetTrsBase,
                                            inTrsValue=ctrlTrsWorldOrigOrient)
                        planeCoords = trsObj.toPlaneCoords(
                            axeNormal=axeLimites[i])

                        #slaveValue
                        self.slaveValue = trsObj.snapOnPlane(
                            planeCoords,
                            inTrsValue=self.slaveValue + [0, 0, 0, 1, 1, 1])

                        #lastSpeed
                        mVectorA = ompy.MVector(
                            planeCoords[1][0] - planeCoords[0][0],
                            planeCoords[1][1] - planeCoords[0][1],
                            planeCoords[1][2] - planeCoords[0][2])
                        mVectorB = ompy.MVector(
                            planeCoords[2][0] - planeCoords[0][0],
                            planeCoords[2][1] - planeCoords[0][1],
                            planeCoords[2][2] - planeCoords[0][2])
                        mVectorMoyen = ompy.MVector(
                            origOffsetTrs[0] - self.slaveValue[0],
                            origOffsetTrs[1] - self.slaveValue[1],
                            origOffsetTrs[2] - self.slaveValue[2])
                        mVectorNormal = utilsMayaApi.get2VectorsNormal(
                            mVectorA, mVectorB, mVectorMoyen)

                        mlastSpeed = ompy.MVector(self.lastSpeed[0],
                                                  self.lastSpeed[1],
                                                  self.lastSpeed[2])

                        if (mVectorNormal * mlastSpeed < 0):
                            self.lastSpeed = self.getReflectVector(
                                self.lastSpeed, planeCoords, collision)

            # OUT ANGLE
            angleOut = self.angleCompute(axeDirWay, ctrlTrsWorld,
                                         ctrlOffsetTrs, self.slaveValue)

            angleOut = [
                activate * angleOut[0], activate * angleOut[1],
                activate * angleOut[2]
            ]

    #_____________________________________________________________________________________ OUT

        nodeName = self.name()
        mc.undoInfo(swf=0)
        mc.setAttr(nodeName + '.' + self.kInput11AttrName, self.nbrEval)
        mc.setAttr(nodeName + '.' + self.kInput12AttrName, self.lastTime)
        mc.setAttr(nodeName + '.' + self.kInput13AttrName,
                   self.lastSpeed[0],
                   self.lastSpeed[1],
                   self.lastSpeed[2],
                   type='double3')
        mc.setAttr(nodeName + '.' + self.kInput14AttrName,
                   self.slaveValue[0],
                   self.slaveValue[1],
                   self.slaveValue[2],
                   type='double3')
        mc.undoInfo(swf=1)

        output = angleOut[0]
        dataHandle = dataBlock.outputValue(self.outputXAttr)
        dataHandle.setFloat(output)

        output = angleOut[1]
        dataHandle = dataBlock.outputValue(self.outputYAttr)
        dataHandle.setFloat(output)

        output = angleOut[2]
        dataHandle = dataBlock.outputValue(self.outputZAttr)
        dataHandle.setFloat(output)

        dataBlock.setClean(plug)
    def compute(self, plug, dataBlock):

        outsAttr = [
            self.outputTXAttr, self.outputTYAttr, self.outputTZAttr,
            self.outputRXAttr, self.outputRYAttr, self.outputRZAttr,
            self.outputSXAttr, self.outputSYAttr, self.outputSZAttr
        ]
        if not (plug in outsAttr):
            return om.kUnknownParameter
    #_____________________________________________________________________________________ IN

        dataHandle = dataBlock.inputValue(self.inputTimeAttr)
        intime = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input1Attr)
        activate = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input3Attr)
        worldMFloatMatrix = dataHandle.asFloatMatrix()
        worldMatrix = MMatrixToNum(worldMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input4Attr)
        mass = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input5Attr)
        elasticity = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input6Attr)
        damping = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input7Attr)
        collision = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input8Attr)
        inMFloatMatrix = dataHandle.asFloatMatrix()
        collisionMatrix = MMatrixToNum(inMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input9Attr)
        hitSphereSize = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input10Attr)
        inMFloatMatrix = dataHandle.asFloatMatrix()
        fatherMatrix = MMatrixToNum(inMFloatMatrix)

        dataHandle = dataBlock.inputValue(self.input11Attr)
        self.nbrEval = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input12Attr)
        self.lastTime = dataHandle.asFloat()

        dataHandle = dataBlock.inputValue(self.input13TAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.lastSpeedT = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input13RAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.lastSpeedR = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input13SAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.lastSpeedS = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input14TAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.slaveTValue = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input14RAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.slaveRValue = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input14SAttr)
        dataHandleNum = dataHandle.asFloat3()
        self.slaveSValue = [
            dataHandleNum[0], dataHandleNum[1], dataHandleNum[2]
        ]

        dataHandle = dataBlock.inputValue(self.input15Attr)
        axeDirWay = dataHandle.asInt()

        #_____________________________________________________________________________________COMPUTE
        trsObj = trsClass.trsClass()

        #_______________ SIGN AXE
        signDir = 1
        axeDir = axeDirWay
        if (2 < axeDir):
            signDir = -1
            axeDir -= 3

    #_______________ DELTA TIME
        incrEval = 0.04
        self.nbrEval += incrEval

        curTime = self.nbrEval
        deltaTime = curTime - self.lastTime
        self.lastTime = curTime

        #_______________ TRS
        initTrsWorld = trsObj.createFromFloatMatrix(worldMatrix)

        # COLLISION INIT

        leadTrsWorld = initTrsWorld

        if not (collision == 0):

            # get vector normal + plane coords
            axeNormal = 0
            trsObj.createFromFloatMatrix(collisionMatrix)

            vectorNormal = trsObj.toTripleVectors()[axeNormal]
            mVectorNormal = ompy.MVector(vectorNormal[0], vectorNormal[1],
                                         vectorNormal[2])
            mVectorNormal.normalize()
            vContact = mVectorNormal * hitSphereSize

            planeCoords = trsObj.toPlaneCoords(axeNormal)

            # RECOMPUTE LEAD : leadTrsWorld
            snapOnPlane = trsObj.snapOnPlane(planeCoords,
                                             inTrsValue=initTrsWorld)
            vSnapInit = ompy.MVector(initTrsWorld[0] - snapOnPlane[0],
                                     initTrsWorld[1] - snapOnPlane[1],
                                     initTrsWorld[2] - snapOnPlane[2])

            if (vSnapInit.length() <=
                    hitSphereSize) or (mVectorNormal * vSnapInit <= 0):
                leadTrsWorld = [
                    snapOnPlane[0] + vContact.x, snapOnPlane[1] + vContact.y,
                    snapOnPlane[2] + vContact.z
                ] + leadTrsWorld[3:9]

    #_______________ DYNAMIC
        curentFrame = mc.currentTime(query=True)
        startFrame = mc.playbackOptions(query=True, minTime=True)

        if (activate == 0) or (curentFrame == startFrame):

            self.nbrEval = 0
            self.lastTime = 0

            self.slaveTValue = leadTrsWorld[0:3]
            self.slaveRValue = leadTrsWorld[3:6]
            self.slaveSValue = leadTrsWorld[6:9]

            self.lastSpeedT = [0, 0, 0]
            self.lastSpeedR = [0, 0, 0]
            self.lastSpeedS = [0, 0, 0]

            self.slaveValue = self.slaveTValue + self.slaveRValue + self.slaveSValue
            self.lastSpeed = self.lastSpeedT + self.lastSpeedR + self.lastSpeedS
            trsOut = leadTrsWorld

        else:

            # DYNAMIC
            self.slaveValue = self.slaveTValue + self.slaveRValue + self.slaveSValue
            self.lastSpeed = self.lastSpeedT + self.lastSpeedR + self.lastSpeedS

            for i in range(0, 9):
                self.slaveValue[i], self.lastSpeed[i] = self.computeDynamic(
                    leadTrsWorld[i], self.slaveValue[i], self.lastSpeed[i],
                    mass, elasticity, damping, deltaTime)

            # activate modulation
            for i in range(0, 9):
                self.slaveValue[i] = self.slaveValue[
                    i] * activate + leadTrsWorld[i] * (1 - activate)

            # out

            self.slaveTValue = self.slaveValue[0:3]
            self.slaveRValue = self.slaveValue[3:6]
            self.slaveSValue = self.slaveValue[6:9]

            self.lastSpeedT = self.lastSpeed[0:3]
            self.lastSpeedR = self.lastSpeed[3:6]
            self.lastSpeedS = self.lastSpeed[6:9]

            # COLLISION

            if not (collision == 0):

                # RECOMPUTE NEXT DYN:   slaveValue   lastSpeed
                snapOnPlane = trsObj.snapOnPlane(planeCoords,
                                                 inTrsValue=self.slaveValue)
                vSnapSlave = ompy.MVector(self.slaveValue[0] - snapOnPlane[0],
                                          self.slaveValue[1] - snapOnPlane[1],
                                          self.slaveValue[2] - snapOnPlane[2])

                if (vSnapSlave.length() <=
                        hitSphereSize) or (mVectorNormal * vSnapSlave <= 0):
                    self.slaveValue = [
                        snapOnPlane[0] + vContact.x, snapOnPlane[1] +
                        vContact.y, snapOnPlane[2] + vContact.z
                    ] + self.slaveValue[6:9]
                    #self.slaveValue = snapOnPlane

                    mLastSpeed = ompy.MVector(self.lastSpeed[0],
                                              self.lastSpeed[1],
                                              self.lastSpeed[2])
                    if (mVectorNormal * mLastSpeed < 0):
                        self.lastSpeed = self.getReflectVector(
                            self.lastSpeed, planeCoords, collision)

            self.slaveTValue = self.slaveValue[0:3]
            self.lastSpeedT = self.lastSpeed[0:3]

            trsOut = self.slaveTValue + self.slaveRValue + self.slaveSValue

    #_____________________________________________________________________________________ OUT NEXT EXAL

        nodeName = self.name()
        mc.undoInfo(swf=0)
        mc.setAttr(nodeName + '.' + self.kInput11AttrName, self.nbrEval)
        mc.setAttr(nodeName + '.' + self.kInput12AttrName, self.lastTime)

        mc.setAttr(nodeName + '.' + self.kInput13TAttrName,
                   self.lastSpeedT[0],
                   self.lastSpeedT[1],
                   self.lastSpeedT[2],
                   type='double3')
        mc.setAttr(nodeName + '.' + self.kInput13RAttrName,
                   self.lastSpeedR[0],
                   self.lastSpeedR[1],
                   self.lastSpeedR[2],
                   type='double3')
        mc.setAttr(nodeName + '.' + self.kInput13SAttrName,
                   self.lastSpeedS[0],
                   self.lastSpeedS[1],
                   self.lastSpeedS[2],
                   type='double3')

        mc.setAttr(nodeName + '.' + self.kInput14TAttrName,
                   self.slaveTValue[0],
                   self.slaveTValue[1],
                   self.slaveTValue[2],
                   type='double3')
        mc.setAttr(nodeName + '.' + self.kInput14RAttrName,
                   self.slaveRValue[0],
                   self.slaveRValue[1],
                   self.slaveRValue[2],
                   type='double3')
        mc.setAttr(nodeName + '.' + self.kInput14SAttrName,
                   self.slaveSValue[0],
                   self.slaveSValue[1],
                   self.slaveSValue[2],
                   type='double3')
        mc.undoInfo(swf=1)

        #_____________________________________________________________________________________ OUT NODE

        fatherTrs = trsObj.createFromFloatMatrix(fatherMatrix)
        trsOutUnder = trsObj.parent(fatherTrs, inTrsValue=trsOut)

        dataHandle = dataBlock.outputValue(self.outputTXAttr)
        dataHandle.setFloat(trsOutUnder[0])

        dataHandle = dataBlock.outputValue(self.outputTYAttr)
        dataHandle.setFloat(trsOutUnder[1])

        dataHandle = dataBlock.outputValue(self.outputTZAttr)
        dataHandle.setFloat(trsOutUnder[2])

        dataHandle = dataBlock.outputValue(self.outputRXAttr)
        dataHandle.setFloat(trsOutUnder[3])

        dataHandle = dataBlock.outputValue(self.outputRYAttr)
        dataHandle.setFloat(trsOutUnder[4])

        dataHandle = dataBlock.outputValue(self.outputRZAttr)
        dataHandle.setFloat(trsOutUnder[5])

        dataHandle = dataBlock.outputValue(self.outputSXAttr)
        dataHandle.setFloat(trsOutUnder[6])

        dataHandle = dataBlock.outputValue(self.outputSYAttr)
        dataHandle.setFloat(trsOutUnder[7])

        dataHandle = dataBlock.outputValue(self.outputSZAttr)
        dataHandle.setFloat(trsOutUnder[8])

        dataBlock.setClean(plug)