Last updated:
Wednesday, September 18, 2002 23:22
HDT (GMT -1000) Click here for the "crosstalk"
solution.
|
A | B |
Figure Specific & General Overall | |
FB - Full Body | |
PB - Partial Body | |
N - Null (used in FB & PB) | N - Null (used in FB & PB) |
M - Morphs | M - Morphs |
J - Joints (XYZ) | J - Joints (XYZ) |
T - Translation (XYZ) | T - Translation (XYZ) |
S - Scale (XYZ) |
S - Scale (XYZ) |
PS - Propagating Scale (XYZ) | PS - Propagating Scale (XYZ) |
Tpr - Taper | Tpr - Taper |
TOff - Translation Offset (XYZ) | TOff - Translation Offset (XYZ) |
Camera Specific | |
Foc - Focal Length | Foc - Focal Length |
H - Hither Distance | H - Hither Distance |
D - Dolly (XYZ) | D - Dolly (XYZ) |
Rll - Roll | Rll - Roll |
Ptch - Pitch | Ptch - Pitch |
Yw - Yaw | Yw - Yaw |
CamAs - Camera Auto Scale | Camas - Camera Auto Scale |
CamAc - Camera Auto Center (XYZ) | CamAc - Camera Auto Center (XYZ) |
CamAf - Camera Auto Focus (XYZ) | CamAf - Camera Auto Focus (XYZ) |
Light Specific | |
Ss - Shadow Strength | Ss - Shadow Strength |
Dms - Depth Map Size/Strength | Dms - Depth Map Size/Strength |
Kd [R/G/B] - Red/Green/Blue Value | Kd [R/G/B] - Red/Green/Blue Value |
KdI - Color Intensity | KdI - Color Intensity |
LfoS - Lite Fall Off Start Angle | LfoS - Lite Fall Off Start Angle |
LfoE - Lite Fall Off End Angle | LfoE - Lite Fall Off End Angle |
LaSD - Lite Atten Start Dist | LaSD - Lite Atten Start Dist |
LaED - Lite Atten End Dist | LaED - Lite Atten End Dist |
Deformer Specific | |
Mag - Magnet | Mag - Magnet |
MagB - Magnet Base | MagB - Magnet Base |
MagZ - Magnet Zone | MagZ - Magnet Zone |
WvP - Wave Phase | WvP - Wave Phase |
WvA - Wave Amplitude | WvA - Wave Amplitude |
WvL - Wave Length | WvL - Wave Length |
WvSt - Wave Stretch | WvSt - Wave Stretch |
WvAN - Wave Amplitude Noise | WvAN - Wave Amplitude Noise |
WvFN - Wave Frequency Noise | WvFN - Wave Frequency Noise |
WvSin - Wave Sinusoidal | WvSin - Wave Sinusoidal |
WvRect - Wave Rectangular | WvRect - Wave Rectangular |
WvTri - Wave Triangular | WvTri - Wave Triangular |
WvTurb - Wave Turbulence | WvTurb - Wave Turbulence |
WvOff - Wave Offset | WvOff - Wave Offset |
To understand how this all works, take a look at the Poser 4 Nude Male. The reason we're looking at this particular figure is because, by default, it has an FBM already applied, and as stated above, FBMs were the basis of these discoveries.
NOTE: Although the code you see on this page may identify "BODY:1", your cr2 file may display a :2/:3/:4...etc in place of ":1". Don't PANIC! Poser automatically assigns these numbers to figures depending on the number of figures in a scene when the cr2 was saved and the order in which they were loaded to the scene. So, as long as the numbers are consistent throughout the entire figure, you will have no problems (If you you have "BODY:2" you will also have rShldr:2, lThigh:2, rForeArm:2 and so on). ** See the crosstalk section [below]!
Open the cr2 in a text editor capable of opening large files... I recommend
EditPadPro
for PC users and BBEdit for Mac users.
WHATEVER YOU DO, SAVE A COPY OF THE CR2
AND WORK FROM IT, NOT THE ORIGINAL.
When you open the cr2, just under the list of actors and the second obj reference, in the head section of the file, you will see this (remember the ":1" I mentioned above) :
----------------snip----------------
actor BODY:1
------ {
------ name GetStringRes(1024,1)
------ off
------ bend 1
------ dynamicsLock 1
------ hidden 0
------ addToMenu 1
------ castsShadow 1
------ includeInDepthCue 1
------ parent UNIVERSE
------ channels
------ ------ {
------ ------ valueParm SuperHero
------ ------ ------ {
------ ------ ------ name SuperHero
------ ------ ------ initValue 0
------ ------ ------ hidden 0
------ ------ ------ forceLimits 0
------ ------ ------ min -100000
------ ------ ------ max 100000
------ ------ ------ trackingScale 0.004
------ ------ ------ keys
------ ------ ------ ------ {
------ ------ ------ ------ static 0
------ ------ ------ ------ k 0 0
------ ------ ------ ------ }
------ ------ ------ interpStyleLocked 0
------ ------ ------ }
----------------snip----------------
The portion beginning with "valueParm" is what is referred to as a null channel. 'Null' in this case means, by itself, it controls nothing. Only by reference from another channel, will it have an affect on any aspect of the figure. The line beginning with "hidden" is a flag (boolean) that determines if the channel is visible to the user. Provided it isn't set to "1", this is what causes the the "SuperHero" dial to show up when you select "BODY" for this particular figure in the Poser UI. There are caveats for targetGeom and ERC linked channels, but for all others... this is true.
When using the "Create Full Body Morph" function in Poser, each morph channel in the selected figure that has a value other than "0" at the moment that the menu item is selected... is given the following 5 lines (though their values may be different), and a "valueParm" channel is inserted at the top of BODY:
----------------snip----------------
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ SuperHero // Control Channel
------ ------ ------ deltaAddDelta 1.000000 // Control Ratio
----------------snip----------------
The first of these, "valueOpDeltaAdd", tells Poser that this channel is the slave of another. The second, "Figure 1", tells Poser which figure has control over this channel. "BODY:1" (the third) tells Poser which group (body part) in the figure has control. The fourth, "SuperHero", tells Poser which channel for that particular body part has control. The fifth, "deltaAddDelta [value]", tells Poser the ratio to use when adjusting the controlling channel. Remember, these same structured lines of code are used in every method of ERC, though their values change.
To figure out the ratio for the "deltaAddDelta [value]" line, you first need to determine the method you intend to apply, then do some simple math:
So where do these lines of code go? Below you'll see where I've inserted "(for reference purposes)". This is so you know what line comes before the lines you insert, following that are the 5 Lines. For channels that are morph related (targetGeom) there are [usually] lines that will follow to establish the number of indexes in the group, the number of deltas (indexes that change) and a list of the deltas with the change (x y z position, at a value of 1). For each channel you want to "slave" to another, these 5 lines must be inserted into the "slave" (affected) channel. With the exception of morph channels, I've found that most channels containing additional lines following the ERC codelines will produce errors.
Non-Morph Channel
----------------snip----------------
------ ------ [Internal Channel Name]
------ ------ ------ {
------ ------ ------ name GetStringRes(1028,2)
------ ------ ------ initValue 0
------ ------ ------ hidden 0
------ ------ ------ forceLimits 0
------ ------ ------ min -45
------ ------ ------ max 45
------ ------ ------ trackingScale 1
------ ------ ------ keys
------ ------ ------ ------ {
------ ------ ------ ------ static 0
------ ------ ------ ------ k 0 0
------ ------ ------ ------ }
------ ------ ------ interpStyleLocked 0 // (for reference purposes)
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ SuperHero // Control Channel
------ ------ ------ deltaAddDelta 1.000000 // Control Ratio
------ ------ ------ }
----------------snip----------------Morph Channel
----------------snip----------------
------ ------ targetGeom [Internal Channel Name]
------ ------ ------ {
------ ------ ------ name [Display Channel Name]
------ ------ ------ initValue 0
------ ------ ------ hidden 0
------ ------ ------ forceLimits 0
------ ------ ------ min -1
------ ------ ------ max 1
------ ------ ------ trackingScale 1
------ ------ ------ keys
------ ------ ------ ------ {
------ ------ ------ ------ static 0
------ ------ ------ ------ k 0 0
------ ------ ------ ------ }
------ ------ ------ interpStyleLocked 0 // (for reference purposes)
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ SuperHero // Control Channel
------ ------ ------ deltaAddDelta 1.000000 // Control Ratio
------ ------ ------ indexes [# of indexes]
------ ------ ------ numbDeltas [# of deltas]
------ ------ ------ deltas
------ ------ ------ ------ [list deltas]
------ ------ ------ }
----------------snip----------------
Null Channel
----------------snip----------------
------ ------ valueParm [Internal Channel Name]
------ ------ ------ {
------ ------ ------ name [Display Channel Name]
------ ------ ------ initValue 0
------ ------ ------ hidden 0
------ ------ ------ forceLimits 0
------ ------ ------ min -1
------ ------ ------ max 1
------ ------ ------ trackingScale 0.004
------ ------ ------ keys
------ ------ ------ ------ {
------ ------ ------ ------ static 0
------ ------ ------ ------ k 0 0
------ ------ ------ ------ }
------ ------ ------ interpStyleLocked 0 // (for reference purposes)
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ SuperHero // Control Channel
------ ------ ------ deltaAddDelta 1.000000 // Control Ratio
------ ------ ------ }
----------------snip----------------
Notice the line "name GetStringRes(1028,2)" in the "Non-Morph Channel" example. Each channel has a name that is used in Poser, and the default named channels use these references to pull names out of a library within Poser's source files. In order to keep the ability for other language versions of Poser to maintain the names in their native languages, you must use these references. I've provided a GetStringRes reference chart (in the tutorials section of this site ) to help you in naming these. You can use fixed names if you like... but your figure will not display dials within Poser of other languages, in that language.
NOTE: Observation of a discussion in one of the poser community forums has lead me to believe the above paragraph needs a little more clarification as to what I mean. It seems that some are confusing my reference to "GetStringRes" and it's location in the code (Display Channel Name) above as saying that this is THE name that must be called by the "Control Channel". This is incorrect. The name that the ERC code points to should be the internal channel name, but can be the external name. Provided either of these names indicate the name called by the "Control Channel" in the ERC code, the connection is established. If the display [external] channel name of one channel and the internal channel name of another channel called by the code are identical, the one with the internal channel name that matches... supersedes control. Your best bet is to always establish links via the internal channel name.
What is Crosstalk?
A problem that exists in Poser 4 is misdirected talking between
figures. This is a fault within Poser 4 introduced with multiple
figures in version 3 and FBM's in version 4, and not one directly attributed
to ERC or any specific figure... though it only becomes apparent when utilizing ERC. "Crosstalk" occurs when identically
named ERC equipped channels are shared between two or more figures that
contain identically named groups (body parts). This is not constrained
by like figures... that is, crosstalk can occur between any number of
figures (or portions of figures) which use identical group naming conventions
and internal channel names in conjunction.
Poser uses "Figure #" by default for naming figures. When a figure, that has one of the ERC methods applied, is loaded after any other like figure, the "Control Figure" points at "Figure 1" (or the first loaded figure of any given figure type) and that presents a problem.
"Fixed Names" as a solution workaround.
One way to sidestep this problem is to use a workaround I found in the
earliest days of EMC when working with CM,
which is fixed names. What I mean by "fixed names" is instead of "Figure
#", use a descriptive name like "Michael" or "Mike Pants" , etc., for the
figure's name. This way when the "Control Figure"
is read by Poser it knows the exact figure in charge, instead
of trying to decipher which figure is "Figure 1" and so-on. Using
fixed names for the name of the figure alone, however, will not correct
the problem. This approach is intended for use on the internal names of the channels
themselves so that Poser no longer confuses it with the names used by the
first figure. Use of a suffix with a preexisting name falls into this
category. Though this approach can prove useful if you intend to keep
multiple copies of any given figure for later use, it isn't very friendly
to language specific versions of Poser, other than the creator's, and again... it doesn't really "solve" crosstalk. The major downfall of this approach, and the reason
it is merely a workaround, is... crosstalk is still present when two or
more of the edited figures (loaded from the same cr2 in the library) are
loaded into the same scene.
The Null Approach.
Another approach (and a much better one), first devised by Charles Taylor
[ nerd3d.com ]
back when all this was still being referred to as EMC,
is the use of a "null" figure. His findings ("EMC Fixer")
solved the issue with Poser 3 and 4 humanoid figures, but
didn't quite remedy the problem in DAZ's Millennium figures or any of
the other unique figures commonly found amongst the various creators.
It also consumed valuable memory within Poser by including
joint information that wouldn't be utilized. I've since re-purposed the
idea for use with ERC and slimmed it down to
what is actually required for it to work.
For the null paradigm, each type of figure needs to have it's own "null" figure which is used while loading subsequent like figures. A "null" figure, is a stripped down cr2 file that lists all of the "actors", but has no actual reference to any geometry or joints. The only 2 required sections, are the head section [version number and list of actors, without "storageOffset" and "geomHandlerGeom" references] and the figure section [all, except the weld list and material list]. The Joint section is not needed, at all.
Here is the "Millennium Null" that I've built to work with DAZ 's Millennium figures, along with the standard Poser 3 & 4 human figures. This file will also work on any figures that use the same or lesser naming conventions as the Millennium figures.
NOTE 1: In order for this to function properly, the desired figure's cr2 must first be prepped, if it hasn't already been done by the creator. That is... all actor/group instances, and references to them, must be ":1". This is in addition to the need for the figure's name, and any references to it, being named "Figure 1". If actor/group instances are not ":1", you can do a global replace of whatever they are (:2, :3, :4.... etc.) with ":1". Such is also the case for the "Millennium Null".
NOTE 2: The steps outlined directly below are provided for cases where you do not intend to save a scene (.pz3) that contains multiple figures. If your intention is to save a scene with more than one ERC equipped figure you should follow the steps outlined in the next sub-section [" And then there was NONE "].
NOTE 3: Your Poser general preferences also need to be prepped for a null to work. Out of the box, Poser loads a figure into the scene... this needs to be changed. There are two ways to accomplish this.
If you have Poser launch to the factory settings, you can comment out (with "//") the "readScript:" command in "Runtime\figures\default.figure".
If, however, you have set a preferred state that Poser loads to, first select the figure and delete it... leaving you with nothing in the scene. Then, select "General Preferences..." from the 'Edit' menu. In the dialog that appears, press the "Set Preferred State" button and click the radio button that says "Launch to Preferred State" next to it. Then hit ok. This will cause poser to load an empty scene at launch and allow you to utilize a null to combat crosstalk.The way this approach works is, after the null is built and saved to your library... you:
1) Beginning with a new scene, load the null (linked above) as your first figure. You will not see anything in the scene yet, this is normal.
2) Then, from the list of "Current Figures" at the bottom left of the working window, make sure the null is selected. Its name is "Millennium Null".
3) From the adjacent list of "Current Elements" make sure "Body" is selected. Once selected "no actor" will appear in it's place.
4) Then "Create New Figure" (double check mark) from the library, loading your first figure with actual geometry.
5) For each time you add an additional figure, follow steps 2 - 5 as needed.The reason using ":1" as described [in the paragraph two above this one] is so important, is... by loading as described above, Poser sees that all instances of ":1" are currently taken by the null so it assigns ":2" in place for the loading figure. When loading a third figure, by having the null selected as described, Poser sees that both ":1" and ":2" are taken and assigns ":3"... effectively stopping crosstalk between like figures.
Herein lies a problem. That problem being that although the null approach as described above does solve crosstalk for the current session, saving your work and later opening the same file (.pz3) will result in a return of the dreaded crosstalk. Unacceptable.
And then there was NONE.
Further controlled experiments, using the null approach, have proven successful
in completely solving the crosstalk issue.
There MUST, however, be "method to your madness".
Okay... so you want to know "how?", right?
1) Beginning with a new scene, load the null (linked above) as your first figure. You will not see anything in the scene yet, this is normal.
2) Then, from the list of "Current Figures" at the bottom left of the working window, make sure the null is selected. Its name is "Millennium Null".
3) From the adjacent list of "Current Elements" make sure "Body" is selected. Once selected "no actor" will appear in it's place.
4) Then "Create New Figure" (double check mark) from the library, loading your first figure with actual geometry.
5) Make any adjustments you want to the figure at this point. Setting values for morphs, rotation, translation, etc. have no effect on the next step.
6) Then, from the list of "Current Figures" at the bottom left of the working window, make sure the null is selected. Again, Its name is "Millennium Null".
6) From the adjacent list of "Current Elements" make sure "Body" is selected. Remember, once selected "no actor" will appear in it's place.
7) Now "Create New Figure" (double check mark) from the library, loading another null. This null is only used as a shield, it should not be selected for loading subsequent figures.
8) With an additional null now in the scene, follow steps 2 - 8 as needed.NOTE 1: With the exception of a figure [clothing] you wish to conform to any other figure in the scene... each time you wish to add another figure, you must first select the null (the original one, named "Millennium Null", without any additional numbers or characters) from the "Current Figure" list, in addition to "Body" from the "Current Element" list, before loading. This includes loading additional nulls.
NOTE 2: With the exception of a figure [clothing] you wish to conform to any other figure in the scene... for each figure you wish to load, you must first load a null to shield the figures from cross-talking when the saved file (.pz3) is opened later.
But... but... I want more!
There will come a time where you'd like to have one channel affected when
more than one other channel is adjusted. This is possible by way of the
sample below. As you can see, all your doing is simply using the same
5 lines of code stacked on top of one another... just referencing different channels.
----------------snip----------------
------ ------ ------ interpStyleLocked 0 // (for reference purposes)
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ Obese // Control Channel
------ ------ ------ deltaAddDelta 1.0 // Control Ratio
------ ------ ------ valueOpDeltaAdd // Identifies the following as the controller
------ ------ ------ ------ Figure 1 // Control Figure
------ ------ ------ ------ BODY:1 // Control Group
------ ------ ------ ------ Emaciated // Control Channel
------ ------ ------ deltaAddDelta -1.0 // Control Ratio
----------------snip----------------
Master? Slave?
In contrast, you'll likely encounter situations where you want one channel
affecting multiple others. The important thing to remember here is that
in every case you aim to use this technology with your own work, you MUST
place the ERC code (the 5 lines referred to throughout
this tutorial) in the slave channel. The slave being the channel where
you want the effect to take place, and the master being where you want
control to stem from.
One thing to keep in mind is, though you can place the master channel in a group of the hierarchy and affect the group(s) above it... due to a redraw issue in Poser 4, any control established beyond a group that is greater than a single level higher (e.g.. Grand parent; the parent's parent) may not redraw until something is done to force Poser to redraw the scene (like moving the camera).
Cascading Control.
This also brings up the topic of cascading control or dependency hierarchies.
By placing ERC code in a slave channel and then
also placing ERC code in that channel's master
(to yet another master), you effectively cascade control from the topmost
master in the chain down to the very last slave. It doesn't stop there
either... because, you can branch control at any level and create subsequent
hierarchies within. Complicated, I know...
Intravenous Drip.
Some have asked whether ERC can be "injected" from an external file.
The answer is yes, but [so far] it cannot be removed in the same manner. If multiple attempts at injecting the code are conducted, what will happen is, Poser will stack each subsequent attempt on top of the previous attempt. Things can get pretty sticky, pretty quick...
Save your edited cr2 and test it in Poser... you'll have to fiddle with the Control Ratio in order to get it "perfect", but at least now the many options of ERC are there. To answer a question that is bound to come up, this approach seems to work on any file format Poser uses that contains channels like those mentioned above, like props and hair...
Copyright © 2000 Robert E. Whisenant. All Rights Reserved. www.rbtwhiz.com
*Special thanks to Chad Smith [DAZ Productions, Inc.] for his editorial comments and enticing questions; keeping my focus sharp.