PDA

View Full Version : Connecting Scripted Ops


JDex
03-10-2007, 03:39 PM
Hey all,

I'm trying to figure out how to use the scripted op from here (http://www.ray-t.net/intersection.htm) in another scene. I've never used a ScOp that didn't have a built in way of setting it up and I'm kind of at a loss now.

The ScOp is in the scene made available on the page and is used on the global kine of the arrow object. I've saved the ScOp as a SPDL from the ScOp editor and have repeatedly tried to add it to a test object (just a sphere) in the provided scene by RMB clicking the Sphere's Kinematics>Global property and Set Scripted Operator... I can then Open the SPDL and it shows up. I've edited all of the connection paths:

Out1 - Out - Sphere.kine.global
InNull - In - Sphere.kine.global
InPolymsh - In - grid.polymsh
InP0kine - start.kine.global
InP1kine - end.kine.global
InPolymshKine - In - grid.kine.global

I have tried this with the arrow in the scene and with it removed from the scene, but have had XSI crash each and everytime I have hit the Apply button.

I'm afraid that the docs on ScOps haven't helped me much, so I was hoping that someone with more scripting/ScOp experience could throw me a bone. Anyone have any idea where I'm going wrong?

Using 5.11 and 6.0 on XP. Thanks.

5quid
03-10-2007, 06:38 PM
I don't think you are doing anything wrong. i've had this crash on even the simplest of scops saved to spdl...so much so, that i never, ever save scops as spdls now.

If you desperately need this intersection scop i'd suggest wrapping it into an apply script (or if you wait till tommorrow, i can do it for you) and using it that way.

ShadowM8
03-10-2007, 08:19 PM
You can rewrite it to be applied by running a script, there are examples in the sdk how to do so.

Take everything in update code and in sub pane as well and make the into a function:

function YouOp_Update (ctx, Out, InNullKine, InPolymsh, InP0Kine, InP1Kine, InPolymshKine) {
Copied code goes here
}

Then:

// Create new scripted operator
oScop = XSIFactory.CreateScriptedOp ("YouOp", "", "JScript");

// Add inputs and outputs
oScop.AddOutputPort (connection.FullName);
oScop.AddInputPort (connection.FullName, "portname");

// Add parameters
oScop.AddParameter (XSIFactory.CreateParamDef2 ("text", siString, "hello"));

// Convert update function to string
codeStr = YouOp_Update.toString();

// Add code and connect operator
oScop.Code = codeStr;
oScop.Connect ();

This should get you started!
Feel free to ask if you've got more questions.

JDex
03-11-2007, 01:06 AM
Thanks for the assistance guys.

5quid... Reading through the SDK makes me think that I was doing something wrong, but at this point it's way above me... only so much mental bandwidth right now. If you do get a chance tomorrow, that would be much appreciated.

ShadowM8... I have tried to do so and follow the SDK examples that I could locate. I keep getting an error:

//ERROR : 'connection' is undefined

I've looked through the code to see if it was a simple typo error or something, but I'm not really versed well enough in the API or jscript to troubleshoot it effectively. Any thoughts on why the error is being thrown?

ShadowM8
03-11-2007, 03:01 AM
Well I poseted the example so no need for sdk other than to check on methods, you pretty much just need to fill the blanks :)

If you have specified an output connection correctly you should be able to connect the operator without a problem. In this case
oScop.AddOutputPort (Arrow.Kinematics.Global.FullName);

Here's the script for you!
Obviously you'd need to change naming as required for your scene.


// Create new scripted operator
oScop = XSIFactory.CreateScriptedOp ("Op", "", "JScript");

// Add inputs and outputs
oScop.AddOutputPort (Dictionary.GetObject("arrow").Kinematics.Global.FullName);
oScop.AddInputPort (Dictionary.GetObject("arrow").Kinematics.Global.FullName, "InNullKine");
oScop.AddInputPort (Dictionary.GetObject("grid").ActivePrimitive.FullName, "InPolymsh");
oScop.AddInputPort (Dictionary.GetObject("start").Kinematics.Global.FullName, "InP0Kine");
oScop.AddInputPort (Dictionary.GetObject("end").Kinematics.Global.FullName, "InP1Kine");
oScop.AddInputPort (Dictionary.GetObject("grid").Kinematics.Global.FullName, "InPolymshKine");

// Add parameters
var param = oScop.AddParameter (XSIFactory.CreateParamDef2 ("NormalOrient", siBool, true));
var param = oScop.AddParameter (XSIFactory.CreateParamDef2 ("Roll", siDouble, 0, 0, 360));

// Convert update function to string
codeStr = Op_Update.toString();

// Add code and connect operator
oScop.Code = codeStr;
oScop.Connect ();

function Op_Update (ctx, Out, InNullKine, InPolymsh, InP0Kine, InP1Kine, InPolymshKine) {
var geo = InPolymsh.Value.Geometry;

var trianlges=geo.Triangles;

var p0Trans=InP0Kine.Value.Transform;
var p0=XSIMath.CreateVector3();
p0Trans.GetTranslation(p0);

var d0Trans=InP1Kine.Value.Transform;
var d0=XSIMath.CreateVector3();
d0Trans.GetTranslation(d0);

d0.SubInPlace(p0);

var Roll = ctx.Parameters("Roll").Value;
var NormalOrientBool = ctx.Parameters("NormalOrient").Value;

var targetMeshMatrix=InPolymshKine.Value.Transform;

var mtx = XSIMath.CreateMatrix4();
targetMeshMatrix.GetMatrix4(mtx);

for(var i=0;i<trianlges.count;i++)
{
var points = trianlges(i).Points;

var A = points.Item(0).Position;
A.MulByMatrix4InPlace(mtx);

var B = points.Item(1).Position;
B.MulByMatrix4InPlace(mtx);

var C = points.Item(2).Position;
C.MulByMatrix4InPlace(mtx);

var n=getNormal(A,B,C);

var d=( A.x * n.x + A.y * n.y + A.z * n.z);

var dot1=p0.dot(n);
var dot2=d0.dot(n);

var t=(d-dot1)/(dot2);

if(t<=1.0)
{
var mt = XSIMath.CreateVector3();
mt.scale(t,d0);

var intersec=XSIMath.CreateVector3();
intersec.add(p0,mt);

var isInside=inside(intersec,A,B,C);

if(isInside)
{
var tx=transform(intersec,n,NormalOrientBool);

Out.Value.Transform=tx;

break;
}
}
}

Out.Value.Roty=Roll;

function transform(intersecVec,normalVec,normOrBool)
{
var upVec = XSIMath.CreateVector3();
upVec.set(0, 1, 0);

var axis = XSIMath.CreateVector3();
axis.cross(upVec, normalVec);

var angle=Math.acos(upVec.dot(normalVec));

var trn=XSIMath.CreateTransform();

trn.SetTranslationFromValues(intersecVec.x,intersecVec.y,intersecVec.z);

if(normOrBool)trn.SetRotationFromAxisAngle(axis,angle);

return trn;
}


function inside(intersVec,vecA, vecB, vecC)
{
var segmentU=XSIMath.CreateVector3();
var segmentV=XSIMath.CreateVector3();

segmentU.sub(vecA,vecB);
segmentV.sub(vecA,vecC);

var uu, uv, vv, wu, wv, w, D;

uu=segmentU.dot(segmentU);
uv=segmentU.dot(segmentV);
vv=segmentV.dot(segmentV);
w=XSIMath.CreateVector3();
w.sub(intersVec,vecA);
wu=w.dot(segmentU);
wv=w.dot(segmentV);
D=uv * uv - uu * vv;

var s, t, ret;
var ret=1;
s=-(uv*wv-vv*wu)/D;
if(s<0.0 || s> 1.0) ret=0;

t=-(uv*wu-uu*wv)/D;
if(t<0.0 || (s+t)>1.0) ret=0;

return ret;
}


function getNormal(vecA, vecB, vecC)
{
var v1 =XSIMath.CreateVector3();
var v2 =XSIMath.CreateVector3();

v1.sub(vecA,vecB);
v2.sub(vecA,vecC);

var outVec=XSIMath.CreateVector3();
outVec.set(0,0,0);
outVec.cross(v1,v2),
outVec.NormalizeInPlace();

return outVec;
}

function drawVec(start,end)
{

var debugVec= SICreateCurve("debugVec", 1, 1);
SIAddPointOnCurveAtEnd(debugVec,start.x, start.y, start.z, false, 0);

if(arguments[1]==null)
SIAddPointOnCurveAtEnd(debugVec,0, 0, 0, false, 0);

else SIAddPointOnCurveAtEnd(debugVec,end.x, end.y, end.z, false, 0)
}
}

JDex
03-11-2007, 05:34 AM
Thanks mate... I'll give it a go in a little while. :bounce:

JDex
03-12-2007, 09:00 AM
Works like a charm... just had to remove some unneeded spaces from lines 103 and 105. Thanks alot man. Now I just gotta talk the boss into making me available for some R&D time for getting back into my scripting studies.

Once again, thanks ShadowM8

ShadowM8
03-12-2007, 01:21 PM
You're welcome!

5quid
03-13-2007, 09:49 AM
I was gazumped!

:)

CGTalk Moderation
03-13-2007, 09:49 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.