Page 2 of 2

Re: Playing animation (IPO) from Python?

Posted: Thu Jul 21, 2011 12:12 pm
by D'Lanor
Yes, it is this section of class plPythonParameter.

Code: Select all

    def _ExportScript(pyfmod,argscript,index,scnobj):
        _type = str(FindInDict(argscript,"type","none"))
        page = pyfmod.data.getRoot()
        resmgr = page.resmanager
        idx = int(FindInDict(argscript,"index",index))

        if plPythonParameter.ScriptValueType.has_key(_type):
            typeinfo = plPythonParameter.ScriptValueType[_type]
            if   typeinfo["type"] == "bool":
                value = bool(str(FindInDict(argscript,"value","false")).lower() == "true")
                param = plPythonParameter(pyfmod)
                param.fValue = value
                param.fID = idx
                param.fValueType = typeinfo["typenum"]
                pyfmod.data.addParameter(param)
            elif typeinfo["type"] == "int":
                value = int(FindInDict(argscript,"value","0"))
                param = plPythonParameter(pyfmod)
                param.fValue = value
                param.fID = idx
                param.fValueType = typeinfo["typenum"]
                pyfmod.data.addParameter(param)
            elif typeinfo["type"] == "float":
                value = float(FindInDict(argscript,"value","0.0"))
                param = plPythonParameter(pyfmod)
                param.fValue = value
                param.fID = idx
                param.fValueType = typeinfo["typenum"]
                pyfmod.data.addParameter(param)
            elif typeinfo["type"] == "str":
                value = str(FindInDict(argscript,"value","0"))
                param = plPythonParameter(pyfmod)
                param.fValue = value
                param.fID = idx
                param.fValueType = typeinfo["typenum"]
                pyfmod.data.addParameter(param)
            elif typeinfo["type"] == "none":
                param = plPythonParameter(pyfmod)
                param.fID = idx
                param.fValueType = typeinfo["typenum"]
                #pyfmod.data.addParameter(param)
            elif typeinfo["type"] == "key":
                ref = FindInDict(argscript,"ref",None)
                plPythonParameter.ExportKey(pyfmod,ref,typeinfo,idx,scnobj)
            elif typeinfo["type"] == "keylist":
                param = plPythonParameter(pyfmod)

                refs = list(FindInDict(argscript,"refs",[]))

                for ref in refs:
                    if type(ref) == str:
                        plPythonParameter.ExportKey(pyfmod,ref,typeinfo,idx,scnobj)

He replaced the automatically assigned index with an AlcScripted variable.

Re: Playing animation (IPO) from Python?

Posted: Thu Jul 21, 2011 12:28 pm
by tachzusamm
Ah, yes, found it now. Thanks.

I will give this a try.

The AlcScript will look like this then, I assume:

Code: Select all

                  - type: animationname      # id 7
                    value: SubRampAnim_02
                    index: 7
                  - type: animation         # id 8
                    ref: :SubWorld_02         # <= here goes the animated object, NOT its animation name!
                    index: 7



EDIT:
Yes! It works like a charm. :idea:

Here's the modified prp_LogicClasses.py script, just for reference. It only differs to the current PyPRP 1.60 trunk in these parts:
- uncommented the line which disabled the animation parameter, plus giving it a default of [006D]
- added Paradox's modification to allow forcing the index (ID) of parameters
prp_LogicClasses_PythonAnimation.zip
(16.13 KiB) Downloaded 317 times


Maybe it could be merged to trunk, because it does not change anything for those who dont use it.

Are animations controlled with Python scripts worth a Wiki article?
I'm guessing Python programmers are a minority, and this thread may be enough to get the idea...


EDIT2:
I forgot to mention that I additionally replaced this codeblock:

Code: Select all

    def export_object(self, obj, objscript):
        plSynchedObject.export_obj(self, obj, objscript)
        # check for animations
        laipo = None
        if obj.type == "Lamp":
            laipo = obj.data.ipo
        if obj.ipo or laipo:
            # this will specify animation names and markers
            animParams = FindInDict(objscript, "animations", [])
            agmm = plAGMasterMod.FindCreate(self.getRoot(), obj.name)
            if(len(animParams) == 0):
                # if there is no script for the animation, make a single animation with all frames
                anim = prp_AnimClasses.plATCAnim.FindCreate(self.getRoot(), obj.name)
                anim.data.export_obj(obj)
                agmm.data.fPrivateAnims.append(anim.data.getRef())
            for animation in animParams:
                # if there are animations defined in alcscript, export each separately
                if(FindInDict(animation, "type", None) == "ageglobalanim"):
                    anim = prp_AnimClasses.plAgeGlobalAnim.FindCreate(self.getRoot(), FindInDict(animation, "name", "unnamed"))
                else:
                    anim = prp_AnimClasses.plATCAnim.FindCreate(self.getRoot(), FindInDict(animation, "name", "unnamed"))
                anim.data.export_obj(obj, animation)
                agmm.data.fPrivateAnims.append(anim.data.getRef())
            agmod = plAGModifier.FindCreate(self.getRoot(), obj.name)
            agmod.data.fChannelName = obj.name
            self.data2.append(agmod.data.getRef())
            self.data2.append(agmm.data.getRef())


with this one:

Code: Select all

    def export_object(self, obj, objscript):
        plSynchedObject.export_obj(self, obj, objscript)
        # check for animations
        laipo = None
        if obj.type == "Lamp":
            laipo = obj.data.ipo
        if obj.ipo or laipo:
            # this will specify animation names and markers
            animParams = FindInDict(objscript, "animations", [])
            agmm = plAGMasterMod.FindCreate(self.getRoot(), obj.name)
            if(len(animParams) == 0):
                # if there is no script for the animation, make a single animation with all frames
                anim = prp_AnimClasses.plATCAnim.FindCreate(self.getRoot(), obj.name + "_(Entire Animation)_anim")
                anim.data.export_obj(obj)
                agmm.data.fPrivateAnims.append(anim.data.getRef())
                #print "CREATED:PRIVATE ANIM"
            for animation in animParams:
                # if there are animations defined in alcscript, export each separately
                if(FindInDict(animation, "type", None) == "ageglobalanim"):
                    anim = prp_AnimClasses.plAgeGlobalAnim.FindCreate(self.getRoot(), obj.name +  "_" + FindInDict(animation, "name", "(Entire Animation)") + "_anim")
                    #print "CREATED:GLOBAL ANIM"
                else:
                    anim = prp_AnimClasses.plATCAnim.FindCreate(self.getRoot(), obj.name +  "_" + FindInDict(animation, "name", "(Entire Animation)") + "_anim")
                    #print "CREATED:PRIVATE ATCAnim"
                anim.data.export_obj(obj, animation)
                agmm.data.fPrivateAnims.append(anim.data.getRef())
            agmod = plAGModifier.FindCreate(self.getRoot(), obj.name)
            agmod.data.fChannelName = obj.name
            self.data2.append(agmod.data.getRef())
            self.data2.append(agmm.data.getRef())


in prp_ObjClasses.py => class plSceneObject(), because that creates ptATCAnim[00F1] entries named like in Cyan Ages.
Don't know if it's necessary though.

(Code taken from GPNMilano's contrib).