Jump to content

Robert Krawczyk

Limited Member
  • Posts

    25
  • Joined

  • Last visited

Everything posted by Robert Krawczyk

  1. Hi, I modified a Character (Mixamo Control Rig) so that instead of the hand driving the weapon, you mainly animate a two-hand weapon control, and the IK hands are constrained to the weapon. But after adding another layer of constraints, the rig is having odd expression priority issues that make it awkward to animate with (see video). My professor says it's because the hands shouldn't be driven by something outside of the Character. Is it really so? - do I have to redo this rig and animation so that the hand drives the weapon? Video of the problem - the hands snap to a weird place when changing frames, and only update when clicking in the viewport (so the expressions evaluate)
  2. I guess using frozen does work! Here's a solution using an ObjectList iterator to loop through one of the tentacles and a Link List operator (aka "Get Object At Index") to get the joint of the same index but on the other tentacle. Note - it seems that you should do Freeze All PSR on the joints in tentacle A so that there are clean values going into the other tentacles. tentacle test.c4d
  3. Would you consider parent constraints? A python script could put a parent constraint on each bone in chain B that targets the respective bone in chain A, based on naming or something. I have a script that should almost do it if you want. By Xpresso, I think you could do it with python + Iterators, but it might not work as expected because I find frozen PSR moves the object a little differently from local PSR, I think maybe frozen is global or something.
  4. You could make a copy of the skeleton (and geo), make sure the copy is in the same exact pose as the original, then delete all the keyframes in the copy, and put a Character Definition tag on both, Extract Skeleton, Create Solver on the copy's Character Definition, and plug in the original's Character Definition into Source. This make the original drive the copy, and it ends up with no frozen transformations. So you can now export the copy with Baking checked, or if that doesn't bake it then do Timeline > Functions > Bake Objects... on the copy's root.
  5. mathnode[c4d.GV_DYNAMIC_DATATYPE] = c4d.DTYPE_VECTOR Set it to c4d.DTYPE_VECTOR, c4d.DTYPE_REAL, etc. Note: Make sure to do this AFTER setting the operation type (in this case, Subtract). Like so: n_Offset = nodemaster.CreateNode(xgroup, c4d.ID_OPERATOR_MATH, x=spacing*5, y=spacing*1) n_Offset[c4d.GV_DYNAMIC_DATATYPE] = c4d.DTYPE_VECTOR ####### IMPORTANT, NOT IN DOCUMENTATION: Setting datatype of nodes n_Offset[c4d.GV_MATH_FUNCTION_ID] = c4d.GV_SUB_NODE_FUNCTION n_Offset.SetName("Offset") This was not in the documentation so I thought I would post it in case someone needs it. Also for convenience here's a full example of setting up a new Xpresso tag (on my "geonulls"), which is sorta documented elsewhere but maybe this can speed things up for you. (I don't use any vectors in this one but it's good to have for constant and math nodes for example) #### XPRESSO START ##### # Set up the Xpresso tag xtag = c4d.BaseTag(c4d.Texpresso) # lol I'm assuming this is supposed to be Xpresso xtag.SetName(xtagname) georoot.InsertTag(xtag) nodemaster = xtag.GetNodeMaster() xgroupname = "Drive GeoNulls" #if nodemaster.SearchNode(xgroupname) != None: remove # Create Xgroup #xgroup = nodemaster.CreateNode(nodemaster.GetRoot(), c4d.ID_GV_OPERATOR_GROUP) xgroup = nodemaster.GetRoot() xgroup.SetName(xgroupname) # Create node for GEO, if we needed to get UserData from it or something #n_thisobj = nodemaster.CreateNode(xgroup, c4d.ID_OPERATOR_OBJECT) geonulls_psr = [] nodeposx_left = 560 nodeposx_right = 400 nodeposy_rowheight = 100 nodeposy_curr = 0 ##### XPRESSO BREAK #### ... for geonull in geonulls: ... ##### XPRESSO RESUME ####### # Create Geonull node n_geonull = nodemaster.CreateNode(xgroup, c4d.ID_OPERATOR_OBJECT, x=nodeposx_left, y=nodeposy_curr) n_geonull[c4d.GV_OBJECT_OBJECT_ID] = geonull p_geonull_gpos = n_geonull.AddPort(c4d.GV_PORT_INPUT, c4d.ID_BASEOBJECT_GLOBAL_POSITION) #p_geonull_rot = n_geonull.AddPort(c4d.GV_PORT_INPUT, c4d.ID_BASEOBJECT_REL_ROTATION) p_geonull_scale = n_geonull.AddPort(c4d.GV_PORT_INPUT, c4d.ID_BASEOBJECT_REL_SCALE) p_geonull_vis = n_geonull.AddPort(c4d.GV_PORT_INPUT, c4d.ID_BASEOBJECT_VISIBILITY_EDITOR) # Create Joint node n_joint = nodemaster.CreateNode(xgroup, c4d.ID_OPERATOR_OBJECT, x=nodeposx_right, y=nodeposy_curr) n_joint[c4d.GV_OBJECT_OBJECT_ID] = joint p_joint_gpos = n_joint.AddPort(c4d.GV_PORT_OUTPUT, c4d.ID_BASEOBJECT_GLOBAL_POSITION) #p_joint_rot = n_joint.AddPort(c4d.GV_PORT_OUTPUT, c4d.ID_BASEOBJECT_REL_ROTATION) p_joint_scale = n_joint.AddPort(c4d.GV_PORT_OUTPUT, c4d.ID_BASEOBJECT_REL_SCALE) p_joint_vis = n_joint.AddPort(c4d.GV_PORT_OUTPUT, c4d.ID_BASEOBJECT_VISIBILITY_RENDER) # Connect the ports p_joint_gpos.Connect(p_geonull_gpos) #p_joint_rot.Connect(p_geonull_rot) p_joint_scale.Connect(p_geonull_scale) p_joint_vis.Connect(p_geonull_vis) nodeposy_curr += nodeposy_rowheight ##### XPRESSO END #### This is the result. For context, the geonulls (right) are named the same as the joints (left)
  6. Hello, is there an easy way to get an object's global position in Python, like Xpresso can do? There is GetRelPos() and GetAbsPos(), I was hoping there would be a GetGlbPos() or something. Current options are doing trigonometry, or creating an Xpresso node every time I need to get global position. Any better ideas? This was my attempt, but it does not take into account rotation, so it gets wrong values. def GetGlobalPos(obj): gpos = obj.GetAbsPos() curr_ancestor = obj.GetUp() while curr_ancestor != None: gpos += curr_ancestor.GetAbsPos() curr_ancestor = curr_ancestor.GetUp() return gpos
  7. Hi, I'm trying to get UserData buttons in an object (not tag) to work, and I have copied code by Cairyn and NiklasR from previous forum posts, but in R23 it seems that 'event_data' might not be a valid key within the message's data parameter. KeyError: 'event_data' Caused by event_data = data['event_data'] Full code: #Predefined global variables : tag, op, proxy, doc, thread, qualifier import c4d from c4d import gui def message(id, data): if id == c4d.MSG_DESCRIPTION_CHECKUPDATE: if len(data["descid"]) > 1 and data["descid"][1].dtype == c4d.DTYPE_BUTTON: userDataId = data["descid"][1].id #gui.MessageDialog("Button " + str(userDataId) + " pressed") if userDataId == 1: gui.MessageDialog("Reading Reference Pose") elif userDataId == 2: gui.MessageDialog("Going to Reference Pose") def message(msg_type, data): if msg_type == c4d.MSG_NOTIFY_EVENT: event_data = data['event_data'] if event_data['msg_id'] == c4d.MSG_DESCRIPTION_COMMAND: desc_id = event_data['msg_data']['id'] if desc_id[1].id == 2: print("Hello!") c4d.SendCoreMessage(c4d.COREMSG_CINEMA, c4d.BaseContainer(c4d.COREMSG_CINEMA_FORCE_AM_UPDATE)) def main(): host = op.GetObject() if not host.FindEventNotification(doc, op, c4d.NOTIFY_EVENT_MESSAGE): bc = c4d.BaseContainer() host.AddEventNotification(op, c4d.NOTIFY_EVENT_MESSAGE, 0, bc) The forum posts I based this on: http://www.plugincafe.com/forum/forum_posts.asp?TID=12182 http://www.plugincafe.com/forum/forum_posts.asp?TID=11042&KW=user+data+button&PID=43468#43468 Also, does anyone know the difference between the two message functions? And what c4d.COREMSG_CINEMA_FORCE_AM_UPDATE does? head_ctrls1.c4d
  8. Cool! Thanks for the in-depth answer. Based on your investigation I think the issue was that I changed the order of the User Data in the Settings Null. I assumed it would be able to figure it out by naming but I guess it goes by ID. My intended behavaior is that when you rotate the shoulder joint, the trap joint squashes or stretches to reach it, so if that's what's happening then you fixed it! The trap joint (and others I will be applying this to) doesn't have any children besides a trap_tip joint with no weight on it, so it seems like scaling works fine. See gif, or file attached Good point about passing in the parameters and global positions themselves rather than the objects - I will keep that in mind for the future especially when using the object's User Data. I've switched over on this project as well, except for the Joint because we still need to access its input ports. stretchy bone test.c4d
  9. Hi, I'm looking to make an Xgroup that has a couple of Link input ports, and then modifies the objects that you plug into them. Essentially pass by reference. How does this work in Xpresso? I'm always sure to create the Object node from an object in the scene of the same type, like in this picture, shoulder and head are both joints. But it sometimes doesn't work and I can't figure out why. This sort of setup has sometimes worked with an Iterator, but not yet with a normal Object output port. Attached is my attempt. It just ends up with undefined ports. stretchy bone test.c4d
  10. Hi, I'm trying to set it up so that when you click on this 'handle' object, it actually selects a different object. This seems to be the intended functionality of the Interaction Tag's Proxy tab, however I can only get it to select both objects, rather than just the second object. Could I have a bit of assistance on how this is done? Scene file is attached, look at "ctrl_shoulder" Thanks! arm rig1_skin_export.c4d
  11. Ah that was it! Thank you! And you're right that controlling the global rotation is not doing what I expect... should I do the local? Or do I have to make it a PSR or Parent constraint?
  12. Well I've scoured my scene and none of those possibilities are true for the scene file I attached. Would you mind taking a look at it?
  13. This is probably a silly question but what exactly does it mean when a Result node is blank? There aren't any missing connections; I don't see what's wrong with this network. File attached, the tag of interest is on ctrl_Hand_IK. arm rig1.c4d
  14. Thanks for the replies, it's cool that there is actually a way to access keyframes. Is there a way to access a marker's frame number? My purpose is to make it easier to move around major time marks. Like if character A grabs character B at frame 1207, there are multiple objects that have a keyframe corresponding to that event, and those keyframes always need to happen at 1207 for the event to look right. This makes it annoying to move the event to 1260, because I would have to move a bunch of keyframes to 1260 and remember which objects, etc. So I want to put a marker at 1207 and give it a list of objects' keyframes which will always lock to the marker's frame number. I would not be animating the movement of keyframes at all. I thought Xpresso would be good for this because it constantly updates. But if that causes problems, is there a way to have Python code that would run every time a marker moves?
  15. Hi, I would like to move keyframes around the timeline with Xpresso - is this possible? Is there any way to access keyframes and markers?
  16. Amazing, thank you! So NodeIterator can iterate through any GeListNode?
  17. Hi, I have done some motion capture so now I have several animated skeletons which I have turned into Motion Clips (in a Motion System tag). The problem is that in each clip the skeleton starts in a different position, but I want it to start at the center of the world. Is there a way to set some offset on a clip? Alternatively, is there an easy way to offset the position of many keyframes at once, so I could edit the animated skeletons themselves? Last resort could be moving them in the F-Curve Editor maybe.
  18. Can't find a way to search through existing Xpresso nodes. Even tried using GeListNodes functions like GetDown()/Next() but those don't access anything besides XGroups it seems. Any way to do this?
  19. Found a possible fix - constraint tags are acknowledged in the C++ documentation, which uses the same variables and such. So I found that c4d.ID_CA_CONSTRAINT_TAG_PSR_WEIGHT, for example, is a working DescID to use while adding a port on a constraint Xpresso node. (However it is not the same 'Weight' you can select from the create node menu - the option is not greyed out after executing the script. So I don't know how to access those exact menu options. But that is more or less another issue.)
  20. The spline wrap deformer could be an alternative to the sweep for you - make a straight/flat eyebrow polygon object then put the spline wrap deformer on it and target the tracer. spline wrap tracer.c4d
  21. Hello, Does anyone know a way to create and access the settings of constraint tags in a script? There is no BaseTag subclass corresponding to Constraint tags (for examples there is one for textures - c4d.Ttexture - but no Tconstraint). The only way I've been able to create a Constraint tag is using CallCommand(100004788, 50048). Now I want to change the settings inside it, but there aren't really any attributes to access... all the elements of the BaseTag object are just None. Anyone know a way to set up constraint tags in python?
×
×
  • Create New...

Copyright Core 4D © 2023 Powered by Invision Community