[Closed] Creating MAXScript DLX function… HELP
I’m a beginner with C++ and the Max SDK… and I’m trying to create my first Maxscript DLX function (following the IntervalArray SDK example :: sigh :: ) and I have some questions…
This function will be used in either a script controller or wire-parameter expression. I’ve been studying/looking at the SDK and I’m getting confused about Reference methods– ReferenceMakers, ReferenceTargets, etc. In Maxscript I can do this by using:
refs.dependents mySubController …and see in the result which array index is the node. So my first question is–
How do I go about getting the owning node (on the C++ side) that has this DLX function specified within one of its controllers?
INode *sourceNode = ???
How do I use NumRefs() and GetReference(int i) to get the source node? Please help… :shrug:
Well, the following code compiled without error… but is it correct??? :surprised Is this the correct way by using:
[size=2][color=cyan]extern RefTargetHandle GetReference([color=cyan]int i);[/color][/color][/size]
/**************************************************
*<
FILE: myDLXfunction.cpp
CREATED BY: Michael Lawler
HISTORY: Started on September 5, 2013
*> Copyright (c) 2013, All Rights Reserved.
**************************************************/
#include "MAXScrpt.h"
#include "Numbers.h" // for handling of MAXScript Integers and Floats
#include "Arrays.h" // for returning a MAXScript array
#include "3DMath.h" // for handling all MAXScript linear algebra classes
extern int NumRefs();
extern RefTargetHandle GetReference(int i);
void myDLXfunctionInit()
{
// TODO: Place initialization code here. This gets called when MAXScript
// goes live during 3ds Max startup.
}
// Declare C++ function and register it with MAXScript
#include "definsfn.h"
def_visible_primitive(myDLXfunction, "myDLXfunction");
Value* myDLXfunction_cf(Value **arg_list, int count)
{
[indent] //********************************
/* Explain function usage here */
//********************************
//Begin function code:
//Get sourceNode containing myDLXfunction in one of its Controllers
//Seems the 1st dependent is always the transform controller and 2nd is node
int ownNode = 2;
RefTargetHandle ownHandle = NULL;
ownHandle->GetReference(ownNode); //should be its node???
INode* sourceNode = (INode*)ownHandle;
Point3 initPos = ( sourceNode->GetNodeTM(0).GetRow(4) );
return &ok;
[/indent]
}
Well, with only a minor amount of frustration… I have finished and compiled the first beta version of my new DLX function: <[size=2]point3> orbitPos { parameters } :wip:[/size]
[size=2][/size]
Now to test it out… hopefully it works as intended and doesn’t crash 3dsMax! Better try it on my old machine to be safe.
If all goes well I will post a video …if not, then back to the drawing board!
Hmmm… getting: “Unknown system exception” when I try to use the function in a wire parameter expression– not very informative! :shrug:
Edit: I tried using “this” pointer when trying to get its references and the compiler error states:
orbitPos\orbitPos.cpp(59) : error C2673: ‘orbitPos_cf’ : global functions do not have ‘this’ pointers
So I think this unknown system exception has to do with the GetReference( ) function… which goes back to my original question… how do I get the owning Node holding an instance of this function? Any expert out there willing to throw me a bone? :hmm:
you probably need to post the entire function code so we can see what you are doing but I don’t think using this is a goer the node should be passed as a function argument.
Thanks Klunk… yeah, when I discovered that global functions do not have a “this” pointer, I added the source node as the first argument parameter.
My intent is to use this function in a wire-parameter expression– wiring a node’s rotation (under a Rotation List Controller) to its own Position_XYZ sub-controller (under a Position List Controller) which uses this orbitPos function to calculate the orbit position for the given rotation… all in an effort to get around illegal self-referencing and dependency loops… with the ultimate goal of trying to get two nodes to orbit each other.
I also plan to create a custom attribute definition to add to the source node to create an animatable targetDistance parameter and weak references to the source and target Node(s) following Paul Neale’s Weak Referencing tutorial… and then use these custom attributes as function inputs.
The entire code project is attached… the code compiles and creates the DLX plugin function; and it’s available in 3ds Max (as an aside, I need to figure out how to add “help” or “show” info on it…) …but when I try to use it, I’m getting stuck in the check type logic… it keeps throwing the runtime error I setup on needing a Number for targetDistance (when I have expressly given it as a number– both floats or ints). I can’t understand why it’s hanging up there. I managed to get past that by not specifying targetDistance… but I get other errors further along complaining about function needing a class or something and got $Point03 at [position]… (don’t recall exact error right now) but it was the source node it was complaining about. So there are some other bugs lurking in there…
The SDK is extremely poorly documented IMO when discussing getting key arguments… and lacking in full examples of such.
Anyways… the code is attached. Thanks Klunk for offering to take a look at it. It’s still a WIP, but ALL feedback (from anyone– especially you DenisT) is welcome!
Oops… I’ve found the source to some of my problems…
To get the translation row it should be:
node->GetNodeTM(t).GetRow(3) …and not GetRow(4)
…because the matrix index starts at zero.
I’ll recompile and give it another try after work today.
UPDATE: So I have a test scene of some point helpers… when I input the following in the listener (and execute) I get:
Test 1:
orbitPos $Point03 $Dummy01.rotation $Point01
** system exception **
[color=deepskyblue]Test 2:
orbitPos $Point03 $Dummy01.rotation $Point01 upNode:$Point02 upAxis:2
[color=#ff0000]– Runtime error: Expected a number for targetDistance, in function orbitPos
[color=plum]So test 2 is telling me it is not liking the default of &unsupplied for targetDistance… but I don’t understand why not… because the logic should catch that and set targetDistance to the distance between the source node and target node on frame 0. So perhaps this is failing because it’s not getting the time value??? Can someone tell me if I’m not getting the time correctly (to evaluate the node transforms)???
Test 3:
orbitPos $Point03 $Dummy01.rotation $Point01 targetDistance:103.126
[color=#ff0000]** system exception **
[color=#fffffe]———————————————————————
Hmmm… not too informative, my hunch is that I’m not getting the time correctly, or maybe I’m not making a live connection to the scene nodes, so the evaluation of [color=#fffffe]
node->GetNodeTM(t).GetRow(3) is failing…
Anybody have any thoughts???
[/color][/color]
[/color][/color]
[/color][/color]
I’m flopping and floundering here…
orbitPos $Point03 $Dummy01.rotation $Point01 upNode:$Point02
– Type error: Call needs function or class, got: $Point_Helper:Point03 @ [-44.061302,-41.762451,0.000000]
…nothing I’ve tried this evening has worked. :shrug:
I found some more errors in my code…
I had:
Matrix3 rotH;
rotH.SetRow(1,row1_rotH);
rotH.SetRow(2,row2_rotH);
rotH.SetRow(3,row3_rotH);
rotH.SetRow(4,_row4);
Matrix3 rotV;
rotV.SetRow(1,row1_rotV);
rotV.SetRow(2,row2_rotV);
rotV.SetRow(3,row3_rotV);
rotV.SetRow(4,_row4);
…which, along with changing the Point3 variable names to match, has been changed to:
Matrix3 rotH;
rotH.SetRow(0,row0_rotH);
rotH.SetRow(1,row1_rotH);
rotH.SetRow(2,row2_rotH);
rotH.SetRow(3,_row3);
Matrix3 rotV;
rotV.SetRow(0,row0_rotV);
rotV.SetRow(1,row1_rotV);
rotV.SetRow(2,row2_rotV);
rotV.SetRow(3,_row3);
Also, there seemed a problem with the “Normalize” function I used. Visual Studio intellisense was telling me that “Normalize” was using:
_D3DVECTOR Normalize( const _D3DVECTOR &v)
Instead of the 3ds Max [color=cyan]“Normalize” Point3 method… so I changed it to use “FNormalize” from the 3ds Max SDK to avoid confusion.[/color]
New source code is attached (…for those of you who downloaded the original code). All feedback and help is greatly appreciated.
Thanks!