Example #1
0
    def Load(source):
        inst = source
        if isinstance(source, basestring):
            inst = pdDm.LoadYamlFileNicely(source)
        projectedDecal = ProjectedDecal()
        for key, val in inst.__dict__.iteritems():
            if key in projectedDecal.__dict__:
                projectedDecal.__dict__[key] = val

        if inst.texturePath:
            projectedDecal.SetTexturePath(inst.texturePath)
        if inst.maskPath:
            projectedDecal.SetMaskPath(inst.maskPath)
        return projectedDecal
    def Load(source):
        """
        'source' is either a respath or a decal instance that needs to be fixed
        because its legacy.
        Backwards compatible decal loader. Use this to load decals at all times.        
        It supports loading in decals that might have been saved out before more attributes
        were added to the class.
        """
        inst = source
        if isinstance(source, basestring):
            inst = pdDm.LoadYamlFileNicely(source)
        projectedDecal = ProjectedDecal()
        for key, val in inst.__dict__.iteritems():
            if key in projectedDecal.__dict__:
                projectedDecal.__dict__[key] = val

        if inst.texturePath:
            projectedDecal.SetTexturePath(inst.texturePath)
        if inst.maskPath:
            projectedDecal.SetMaskPath(inst.maskPath)
        return projectedDecal
    def SetupWrinkleMapControls(self, avatar, effects, pdDoll):
        if avatar is None:
            return
        set = trinity.TriCurveSet()
        set.name = 'Wrinkles'
        for s in avatar.curveSets:
            if s.name == 'Wrinkles':
                for bind in s.bindings:
                    if hasattr(bind, 'copyValueCallable'):
                        bind.copyValueCallable = None

                avatar.curveSets.remove(s)
                break

        avatar.curveSets.append(set)
        weakAvatar = blue.BluePythonWeakRef(avatar)
        pdDoll.LoadBindPose()

        def CreateBoneDriver(set, bone1, bone2, zone, min, max, oldMin, oldMax, curveDictionary, name, tweakData):
            if bone1 in pdDoll.bindPose and bone1 in pdDoll.boneOffsets and bone2 in pdDoll.bindPose and bone2 in pdDoll.boneOffsets:
                bindPosePos1 = pdDoll.bindPose[bone1]['translation']
                offset1 = pdDoll.boneOffsets[bone1]['translation']
                bindPosePos2 = pdDoll.bindPose[bone2]['translation']
                offset2 = pdDoll.boneOffsets[bone2]['translation']
                realPos1 = (bindPosePos1[0] / 100.0 + offset1[0], bindPosePos1[1] / 100.0 + offset1[1], bindPosePos1[2] / 100.0 + offset1[2])
                realPos2 = (bindPosePos2[0] / 100.0 + offset2[0], bindPosePos2[1] / 100.0 + offset2[1], bindPosePos2[2] / 100.0 + offset2[2])
                bindPoseDist = geo2.Vec3Distance(bindPosePos1, bindPosePos2) / 100.0
                dist = geo2.Vec3Distance(realPos1, realPos2)
                multiplier = dist / bindPoseDist
                oldMin = oldMin * multiplier
                oldMax = oldMax * multiplier

            def GetOrMakeCurve(bone, set, curveDictionary, name):
                curve = curveDictionary.get((weakAvatar, bone), None)
                if curve is not None:
                    return curve
                curve = trinity.Tr2BoneMatrixCurve()
                curve.bone = bone
                curve.name = name
                curveDictionary[weakAvatar, bone] = curve
                set.curves.append(curve)
                return curve

            curve1 = GetOrMakeCurve(bone1, set, curveDictionary, 'bone1')
            curve2 = GetOrMakeCurve(bone2, set, curveDictionary, 'bone2')
            bind = trinity.TriValueBinding()
            set.bindings.append(bind)

            def distanceBinding(curve1, curve2, min, max, parameters, index, gamma):
                avatar = weakAvatar.object
                if avatar is None:
                    return
                curve1.skinnedObject = avatar
                curve2.skinnedObject = avatar
                if curve1.startValue == curve1.currentValue or curve2.startValue == curve2.currentValue:
                    curve1.skinnedObject = None
                    curve2.skinnedObject = None
                    return
                p1 = curve1.currentValue[3]
                p2 = curve2.currentValue[3]
                dist = geo2.Vec3Distance(p1, p2)
                d = 1.0 - (dist - min) * 1 / (max - min)
                if d < 0:
                    d = 0
                elif d > 1:
                    d = 1
                if gamma != 1.0:
                    d = math.pow(d, gamma)
                if False:
                    trinity.GetDebugRenderer().DrawLine((p1[0], p1[1], p1[2]), 4294967295L, (p2[0], p2[1], p2[2]), 4294967295L)
                    trinity.GetDebugRenderer().Print3D((p1[0], p1[1], p1[2]), 4294967295L, str(dist))
                    trinity.GetDebugRenderer().Print3D((p2[0], p2[1], p2[2]), 4294967295L, str(d))
                for p_ in parameters:
                    p = p_.object
                    if p is None:
                        continue
                    if index == 1:
                        p.v1 = d
                    if index == 2:
                        p.v2 = d
                    if index == 3:
                        p.v3 = d
                    if index == 4:
                        p.v4 = d

                curve1.skinnedObject = None
                curve2.skinnedObject = None

            zone = zone - 1
            paramIndex = zone / 4 + 1
            index = zone % 4 + 1
            param = 'WrinkleNormalStrength' + str(paramIndex)
            parameters = []
            for fx in effects:
                for p in fx.parameters:
                    if p.name == param:
                        parameters.append(blue.BluePythonWeakRef(p))

            gammaCurves = tweakData.get('gammaCurves', {})
            gamma = gammaCurves.get(name, gammaCurves.get('default', 1.0))
            bind.copyValueCallable = lambda source, dest: distanceBinding(curve1, curve2, oldMin, oldMax, parameters, index, gamma)

        def CreateAxisDriver(set, jointName, zone, axis, maxValue, name, tweakData, pdDoll):
            avatar = weakAvatar.object
            if avatar is None or not hasattr(avatar, 'animationUpdater') or avatar.animationUpdater is None or not hasattr(avatar.animationUpdater, 'network') or avatar.animationUpdater.network is None:
                return
            bind = trinity.TriValueBinding()
            set.bindings.append(bind)
            if not hasattr(avatar.animationUpdater, 'network'):
                return
            jointIndex = avatar.animationUpdater.network.GetBoneIndex(jointName)
            if jointIndex == -1:
                print "Error: Can't find bone for axis control: " + jointName
                return
            if not type(jointIndex) == type(1):
                print 'Non-int returned for bone in axis: ' + str(jointIndex) + ', name:' + jointName
                return
            bindPosePos = pdDoll.bindPose[jointName]
            if jointName in pdDoll.boneOffsets:
                offset = pdDoll.boneOffsets[jointName]
            else:
                offset = {'translation': [0, 0, 0]}
            startPos = [0,
             0,
             0,
             0,
             0,
             0,
             0,
             0,
             0,
             (bindPosePos['translation'][0] + offset['translation'][0]) / 100.0,
             (bindPosePos['translation'][1] + offset['translation'][1]) / 100.0,
             (bindPosePos['translation'][2] + offset['translation'][2]) / 100.0]

            def AxisBinding(startPos, jointIndex, axis, maxValue, parameters, index, gamma):
                avatar = weakAvatar.object
                if avatar is None:
                    return
                if not hasattr(avatar.animationUpdater, 'network') or avatar.animationUpdater.network is None:
                    return
                newPos = avatar.animationUpdater.network.GetRawTrackData(jointIndex)
                diff = (newPos[9] - startPos[9], newPos[10] - startPos[10], newPos[11] - startPos[11])
                value = 0
                if axis == 'x':
                    value = diff[0]
                elif axis == 'y':
                    value = diff[1]
                elif axis == 'z':
                    value = diff[2]
                finalValue = 0
                max = maxValue
                if max < 0:
                    max = -max
                    value = -value
                if value > max:
                    finalValue = 1.0
                elif value < 0:
                    finalValue = 0.0
                else:
                    finalValue = value / max
                if gamma != 1.0:
                    finalValue = math.pow(finalValue, gamma)
                for p_ in parameters:
                    p = p_.object
                    if p is None:
                        continue
                    if index == 1:
                        p.v1 = finalValue
                    if index == 2:
                        p.v2 = finalValue
                    if index == 3:
                        p.v3 = finalValue
                    if index == 4:
                        p.v4 = finalValue

            zone = zone - 1
            paramIndex = zone / 4 + 1
            index = zone % 4 + 1
            param = 'WrinkleNormalStrength' + str(paramIndex)
            parameters = []
            for fx in effects:
                for p in fx.parameters:
                    if p.name == param:
                        parameters.append(blue.BluePythonWeakRef(p))

            gammaCurves = tweakData.get('gammaCurves', {})
            gamma = gammaCurves.get(name, gammaCurves.get('default', 1.0))
            bind.name = 'AxisBind'
            bind.copyValueCallable = lambda source, dest: AxisBinding(startPos, jointIndex, axis, maxValue, parameters, index, gamma)

        rootFolder = 'R:/'
        if not legacy_r_drive.loadFromContent:
            rootFolder = 'res:/'
        faceSetupPath = rootFolder + 'Graphics/Character/Global/FaceSetup/BasicFace.face'
        if pdDoll.gender != pdDef.GENDER.FEMALE:
            faceSetupPath = rootFolder + 'Graphics/Character/Global/FaceSetup/BasicFaceMale.face'
        if not blue.paths.exists(faceSetupPath):
            return
        data = pdDm.LoadYamlFileNicely(faceSetupPath)
        faceTweaksPath = rootFolder + 'Graphics/Character/Global/FaceSetup/FaceTweakSettings.yaml'
        tweakData = pdDm.LoadYamlFileNicely(faceTweaksPath)
        curveDictionary = {}
        if data:
            for d in data:
                entry = data[d]
                if len(entry) == 7:
                    CreateBoneDriver(set, entry[0], entry[1], entry[2], entry[3] / 100.0, entry[4] / 100.0, entry[5] / 100.0, entry[6] / 100.0, curveDictionary, d, tweakData)
                elif len(entry) == 4:
                    CreateAxisDriver(set, entry[0], entry[1], entry[2], entry[3] / 100.0, d, tweakData, pdDoll)

        wrinkleMultiplier = tweakData.get('wrinkleMultiplier', 1.0)
        correctionMultiplier = tweakData.get('correctionMultiplier', 1.0)
        for fx in effects:
            for p in fx.parameters:
                if p.name == 'WrinkleParams':
                    p.value = (wrinkleMultiplier,
                     correctionMultiplier,
                     0.0,
                     0.0)

        set.Play()
        return set
Example #4
0
    def ImportCharacter(factory, scene, resPath, **kwargs):
        """
        'factory' is an instance of Factory
        'scene' is a reference to the scene into which the character should appear
        'resPath' is the path to the directory which the character was exported to
        'callBack' if provided, is a function that gets called once importing is done.
        
        Imports a character from the given resPath and adds it to the scene.
        This character will not have a doll instance, it is purely a trinity setup of a character.
        Returns a PaperDollCharacter instance
        """
        blocking = kwargs.get('blocking')
        callBack = kwargs.get('callBack')
        rotation = kwargs.get('rotation')
        position = kwargs.get('point')
        pdc = PaperDollCharacter(factory)
        pdc.scene = scene
        pdc.avatar = trinity.Load(resPath + '/unique.red')
        if pdc.avatar is None:
            log.LogInfo('Import failed on ' + resPath + '/unique.red')
            return
        pdc.visualModel = pdc.avatar.visualModel
        slash = resPath.rfind('/')
        pdc.avatar.name = str(resPath[slash + 1:] + ' (import)')
        if position:
            pdc.avatar.translation = position
        if rotation:
            pdc.avatar.rotation = rotation
        rf = blue.ResFile()
        bsPath = resPath + '/blendshapes.yaml'
        meshes = None
        morphTargets = pdDm.LoadYamlFileNicely(bsPath)
        if morphTargets:
            meshes = pdc.visualModel.meshes

        def fun():
            if meshes:
                factory.ApplyMorphTargetsToMeshes(meshes, morphTargets)
                if trinity.GetShaderModel() == 'SM_2_0_LO':
                    pdPor.PortraitTools.RebindDXT5ShadersForSM2(meshes)
            if callBack:
                callBack()

        if blocking:
            fun()
        else:
            uthread.worker('paperDoll::PaperDollCharacter::ImportCharacter',
                           fun)
        scene.AddDynamic(pdc.avatar)
        aoPath = resPath + '/animationOffsets.yaml'
        animationOffsets = pdDm.LoadYamlFileNicely(aoPath)
        if animationOffsets:
            pdc.ApplyAnimationOffsets(animationOffsets)
        pdc.avatar.explicitMinBounds = (-5, -5, -5)
        pdc.avatar.explicitMaxBounds = (5, 5, 5)
        pdc.avatar.useExplicitBounds = True
        if SkinSpotLightShadows.instance is not None:
            for mesh in pdc.visualModel.meshes:
                SkinSpotLightShadows.instance.CreateEffectParamsForMesh(mesh)

        return pdc