Wednesday, November 26, 2008

Muscle Systems may be a little too heavy

Having gone back to working on the dog, I've really had a chance to experience the fun of 5 minute file load times. Basically, each muscle system has a ridiculous number of utility nodes that take a really long time to load up. I think I'm going to need to clean the muscle system up somehow as the graph on just 1 muscle is a little ridiculous (see below). There's a couple solutions I've come up with that might help.



1) See if there's any room to use expressions in the place of utility node driven equations, in general, I used utility nodes because they update when their values change, rather than when the time changes, making for a better UI experience. However, I'm assuming (I haven't looked at the script in a while) that there were places I used utility nodes where it wasn't entirely necessary. I could probably root out a few of those. Of course, I'd have to script some way to repair the existing muscles on my dog as well, without having to rebuild them.

2) Find a better solution regarding multitendonous muscles. I had previously just built several identical muscles on top of each other and moved their tendons so it looked like 1 muscle with several tendons. Aside from this probably causing problems later on with regards to muscle's affecting each other, this really bloats the system. I'll probably want to figure out some way to add additional tendons to these muscles and just parent them to the ends of the belly, so as to avoid the extra utility nodes.

Mirrored muscles turn out to be problematic after all

When I was first setting up my muscles, I figured that I'd need to come up with some fancy method of mirroring them. But I figured I'd first try just scaling them in -X to see if that would be a viable solution. At the time, I was surprised to see that it worked really well. All the controls, flexing, and whatnot still seemed to work. However, now that I'm trying to surface constraint them, I'm coming up with problems as a result (as seen below).



Right now I'm working on a script that will duplicate the original curves on each muscle that defines its shape, scale those in -X, run the joint building script with values of the original muscle, and then apply any transforms in inverse that have been performed on the muscle control curves. Unless anyone can think of a better way?

Wednesday, November 12, 2008

Surface Constraint

I set about to create my surface constraint setup script for attaching my muscles to bones. As a pleasant change of pace, it was a rather successful process. I emulated the method used in the original Rivet (button) script in which I attached a locater to a lofted surface defined by 2 edges on a polygonal surface. I added functionality by which the locater is automatically placed at the point on the surface closest to the object, rather than assuming a 0.5,0.5 uv location. I also allow the user to additionally tweak this position. Once the user is happy with this positioning, they can parent it to see how it works. Assuming this works out properly, the user can then bake the data that defines this constraint to the bone attribute file. The entry for each muscle follows the form:

muscle name, face defining edge1, face defining edge2, uPosition, vPosition, offset from face Vector, and which end of the muscle to parent (i.e. insertion or origin)

Once properly setup, each bone attribute file will have stored each muscle that can attach to it and where. The second part of the script, the constraint rebuild, will take a muscle and a bone as its input and read the attribute file to replace the muscle in its original position. Using the offset vector, it can replace the muscle in its original position, even if the bone has moved since original setup. This will be essential when generating parts on the fly. All thats left to do now, regarding this aspect, is go through the dog model and add each muscle position to each bone attribute file.

Below, see the script in action:



3 aspects to muscle flexing: Free Feature!

I was speaking with Will Telford during his visit about my thesis. With regards to my muscles, he commented that muscle flexing is dependent on 3 different conditions, rather than the single condition I currently have. The 3 conditions he mentioned are based on end point position, motion based, and action based. End point position flexes the muscles as the origin and insertion points grow closer together and unflexes as they grow further apart, this has already been implemented. Motion based suggests that certain actions will flex some muscles more than others, for example, pronation of the arm with flex the bicep more, while supination will flex the tricep more. At Rhythm & Hues they do this with scripts that fire muscles based on detected movement. Since my thesis is pose based (i.e. no movement to detect), this would have to be user controlled. The third, action based, suggests, for example, that a bicep would be far more flexed if the character was holding a 50lb weight over a feather. At Rhythm & Hues, this is animator controlled with a slider, and would be similarly controlled for my thesis. So, the 2 missing aspects of the muscle flex, in the case of my thesis, would have to be user controlled rather than automated, likely with some sort of slider. I have already implemented this slider for muscle generation and shaping, so its a simple matter to integrate it into the UI and call it a feature. So thats a much more advanced solution to muscle flexing without any additional work required.

Wednesday, November 5, 2008

Muscle Shifting [muscleShiftV2.0.py?]

I've found a couple glaring problems with muscleShiftV1 that I can't really figure out how to surmount at present, although it may just require a second conversation with Dr. Keyser.

The first is getting shifted muscles to deform as though they are getting pushed instead of just maintaining their shape. To deal with this, I thought it would be a good idea to get the magnitude of its intended displacement vector and then normalize this vector, multiplying it by the magnitude minus the distance between the 2 circles. This is great when the direction of the displacement vector is in the same direction as the 2 points you're measuring to get distance, not so great when its different. I'm not really sure how to measure the distance between 2 ellipses given a vector (although there's probably a way to do it).

The second problem I'm running into is that the shifting muscles always move along with the guide muscle if it determines the muscles are close enough to be shifted (i.e. they have intersecting bounding boxes). This is often fine, but there are cases (such as if a muscle goes backwards or up) that don't work right (see diagram below). What I need to do is make them shift only if 1 muscle passes through the other as its moving, which is getting me back to physically based simulation territory.

I'm feeling like I should maybe take another look at a hair dynamics solution again. While there were certainly several disadvantages to this method that I saw when I first looked into them, they seem like they might be more surmountable. Then again, other problems seem less surmountable, so maybe that's just frustration talking.

Tuesday, November 4, 2008

A thought for later regarding merging skin parts

During my Dreamworks interview, I was asking about the crazy smears that some of their rigs allowed. Apparently, they avoid the meshes breaking down by turning them into a sort of springy mesh that they can then relax to get more evenly spaced out vertices after stretching and the like. This may be something to look at, in addition to various smoothing techniques, when I come to the problem of merging all the skin mesh parts into a full creature.

Primary Muscle Shift w/Bones

So it occurred to me that I've been spending a lot of time figuring out how my muscles are going to interact with each other and pretty much taking the fact that they'll stick to the bones to get their primary movement as a given. I decided I should look into that and figure out how I'm actually going to do it. After a bit of research, I found that constraining an object to an arbitrary point on a mesh is generally referred to as "riveting", at least amongst the people writing the scripts that do it. I found 2 implementations that seemed like good approaches.

The first is Rivet (button) 1.0 which works by allowing the user to select 2 edges which it then creates a loft node between. It then uses a pointOnSurface node to drive a locators position and the surface tangent of the loft to drive an aim constraint for orientation. This method works rather well, however it requires the locator be exactly in the center of the 2 edges. The muscle control object would have to be parented to the locator with an offset, which could result in some imprecision. However, I believe that the creator of the muscles could probably setup the muscles to have more custom muscles that would implement a u,v positioning other than the 0.5, 0.5 that the original script assumes. Another problem with this script is that it requires the user to specify which edges it will be using. In the case where muscles need to attach to a part of another creature, it will need to know where its supposed to attach. This would probably have to be stored somewhere, associated with each bone of each creature for every muscle that must attach to it.

The second script, djRivet, which actually credits the original script works by creating a Maya hair follicle at the closest place on the mesh it is attaching to, and parents the object to the follicle. This solution, while more precise on positioning, has several disadvantages. It doesn't maintain orientation as well as rivet. It relies on finding the closest point to the object on the mesh, which isn't generally what I'll want for this case, as where the muscle needs to go and where the closest point on the mesh are will often be very different things. Additionally, this method requires the object has non-overlapping uv's, which would require an extra, otherwise unneccesary step of uv-mapping the bones. And finally, this relies on Maya hair follicles, which is a departure from my policy of avoiding Maya-specific tools.

As such, the original riveting method will probably work out best for my needs. With a few tweaks to the implementation, and the creation of some additional data in the existing bone attribute files, it should work well.

Wednesday, October 29, 2008

Muscle Shifting [muscleShiftV1.1.py]

I took my AABB-based muscle intersection finding script and tried to merge it with my muscle shifting script. They weren't integrating smoothly so I decided to rewrite the muscle moving script, setup specifically for the AABB script. I also changed some of the functionality of the script, having it work by the closest 2 control circles instead of just 1. This way the muscles shift better, even if the position matching muscle's control circles are between 2 of the shifting muscle controls. It weights the influence of the 2 control curves based on the percentage between each shifting muscle control curve the matching control curve is found. The matching is still far from perfect. I think it might help if I move the circles by the sum of the radii of the 2 circles (or the sum of the radius of the matching circle and the average of the 2 other circles) and multiply that by the normalized vector that it was currently moving, so the muscles only shift as much as they have to. Anyhow, here's some screenshots of how its currently working: