Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. will_blizzard
    W

    will_blizzard

    @will_blizzard

    0
    Reputation
    2
    Posts
    1
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    will_blizzard Follow

    Best posts made by will_blizzard

    This user hasn't posted anything yet.

    Latest posts made by will_blizzard

    RE: Modify rotation of clone child objects

    @m_magalhaes

    Hi there,

    Well, I figured it out, and have no issue rendering to picture viewer with python effector, so not sure what you're referring to, but maybe the bug is fixed?

    Here is the code that works as intended, although it requires a frame update to change. I'm guessing I can fix that as well with a bit more tinkering. This works as intended with the cloner in either instance or render instance mode.

    from typing import Union
    import c4d
    from c4d.modules import mograph as mo
    from c4d import utils
    
    op: c4d.BaseObject # The python effector
    
    gen: c4d.BaseObject # The MoGraph Generator executing the effector
    doc: c4d.documents.BaseDocument # The document evaluating this effector
    thread: c4d.threading.BaseThread # The thread executing this effector
    
    
    def SetTarget (objMx, target):
        pos2 = target[c4d.ID_BASEOBJECT_REL_POSITION]
        pos1 = objMx.off
    
        vec3=(pos2-pos1).GetNormalized()
        vec2=vec3.Cross(c4d.Vector(0,1,0)).GetNormalized()
        vec1=vec3.Cross(c4d.Vector(1,0,0)).GetNormalized()
        newMx = c4d.Matrix(pos1,vec1,vec2,vec3)
        newRot = c4d.utils.MatrixToHPB(newMx)
        return newRot
    
    def main() -> Union[c4d.Vector, float, int]:
        # Called when the effector is executed to set MoGraph data.
        target = doc.SearchObject("TargetNull")
        if (target == None): return False
    
        moData = c4d.modules.mograph.GeGetMoData(gen)
        marr = moData.GetArray(c4d.MODATA_MATRIX)
    
        cloneSource = gen.GetCache().GetDown()
        clones = []
    
        while cloneSource != None:
            clones.append(cloneSource)
            cloneSource = cloneSource.GetNext()
    
        cnt = len(clones)
    
        frame = doc.GetTime().GetFrame(doc.GetFps())
        for i in range(cnt):
            fixt = clones[i]
            base = fixt.GetDown()
            yoke = base.GetDown()
            head = yoke.GetDown()
    
            newRot = SetTarget(marr[i], target)
            head.SetRelRot(c4d.Vector(0,newRot.y,0))
            yoke.SetRelRot(c4d.Vector(newRot.x,0,0))
    
        moData.SetArray(c4d.MODATA_MATRIX, marr, False)
        c4d.EventAdd()
        return True
    
    posted in Cinema 4D SDK •
    Modify rotation of clone child objects

    Hi there,

    Sorry if this has been asked and answered before, but I've been searching in vain for days for a solution and can't figure it out.

    I'm trying to write a python effector which will mimic the target effector, but which will allow me to separate specifically the heading and pitch onto two separate child objects of a clone.

    The use case is to be able to clone 3D models of moving lights (where the arm assembly rotates( heading) and has a rotating (pitch) head attached to it) and use a target effector-like system to have the models follow a null. The clones are set up as follows:

    Null Parent (The fixture root)
    ---Fixture base geometry (this is the part of the fixture that doesn't move)
    ---Null (The fixture arms, should react to heading)
    ---Arm geometry
    ---Null (The fixture head, should react to pitch)
    ---Head geometry and light

    Screenshot 2022-05-18 001315.png
    I've tried every iteration of constraint and protection tags I can think of, and also have a python effector which modifies ALL of the clones children to follow the target, but does not modify each individual clone's children individually (as the target effector would).

    The python effector script I've written is below:

    from typing import Union
    import c4d
    from c4d.modules import mograph as mo
    from c4d import utils
    
    op: c4d.BaseObject # The python effector
    
    gen: c4d.BaseObject # The MoGraph Generator executing the effector
    doc: c4d.documents.BaseDocument # The document evaluating this effector
    thread: c4d.threading.BaseThread # The thread executing this effector
    
    
    def SetTarget (objMx, target):
        pos2 = target[c4d.ID_BASEOBJECT_REL_POSITION]
        pos1 = objMx.off
        vec3=(pos2-pos1).GetNormalized()
        vec2=vec3.Cross(c4d.Vector(0,1,0)).GetNormalized()
        vec1=vec3.Cross(c4d.Vector(1,0,0)).GetNormalized()
        newMx = c4d.Matrix(pos1,vec1,vec2,vec3)
        newRot = c4d.utils.MatrixToHPB(newMx)
        # print(newRot)
        #obj.SetMl(new_mx)
        return newRot
    
    def main() -> Union[c4d.Vector, float, int]:
        
        target = doc.SearchObject("TargetNull")
        if (target == None): return False
    
        moData = mo.GeGetMoData(op)
        gen = moData.GetGenerator()
        cnt = moData.GetCount()
        cntArray = moData.GetArrayCount()
        marr = moData.GetArray(c4d.MODATA_MATRIX)
        clarr = moData.GetArray(c4d.MODATA_CLONE)
        fixt = gen.GetDown()
        base = fixt.GetDown()
        yoke = base.GetDown()
        head = yoke.GetDown()
    
        for i in range(cnt):
            newRot = SetTarget(marr[i], target)
            head.SetRelRot(c4d.Vector(0,newRot.y,0))
            yoke.SetRelRot(c4d.Vector(newRot.x,0,0))
    
        #moData.SetArray(c4d.MODATA_MATRIX, marr, False)
        c4d.EventAdd()
        return True
    

    I can provide the c4d file as well if necessary, but hopefully what i've noted above makes sense.

    Thanks in advance for the help.
    Will

    posted in Cinema 4D SDK •