jkunz07 Posted July 22, 2015 Share Posted July 22, 2015 I have a function I'm trying to define in a wrangle. If I use the code below in an attribute/point wrangle everything works OK. vector slerpv(vector a_vec; vector b_vec; float bias) { float a_mag = length(a_vec); a_vec = normalize(a_vec); float b_mag = length(b_vec); b_vec = normalize(b_vec); vector4 a_quat = quaternion(a_vec); vector4 b_quat = quaternion(b_vec); vector out_vec = qconvert(slerp(a_quat, b_quat, bias)); out_vec = normalize(out_vec); return out_vec *= lerp(a_mag, b_mag, bias); } vector a = set(1,0,0); vector b = set(0,1,0); v@N = slerpv(a, b, fit(sin(@Time),-1,1,0,1)); If I try change the last line of the above code to multiply one of the first two arguments like so: v@N = slerpv(a, b*5.0, fit(sin(@Time),-1,1,0,1)); I get the following errors and the node will error out. Error: The sub-network output operator failed to cook: /obj/geo1/attribwrangle7/attribvop1 Error: Error in VOP 'snippet1'. Warning: Errors or warnings encountered during VEX compile: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27). Error: Error in VOP 'snippet1'. Warning: Errors or warnings encountered during VEX compile: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27). Error: Vex error: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27) Failed to resolve VEX code op:/obj/geo1/attribwrangle7/attribvop1Unable to load shader 'op:/obj/geo1/attribwrangle7/attribvop1'. Warning: Message node has warning. ____________________________________________________________________________________________________________________________________ Messages from attribvop1: Error: Error in VOP 'snippet1'. Warning: Errors or warnings encountered during VEX compile: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27). Error: Error in VOP 'snippet1'. Warning: Errors or warnings encountered during VEX compile: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27). Error: Vex error: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter. (16,27) Failed to resolve VEX code op:/obj/geo1/attribwrangle7/attribvop1Unable to load shader 'op:/obj/geo1/attribwrangle7/attribvop1' Does anyone know how I can fix this? Quote Link to comment Share on other sites More sharing options...
ChristopherC Posted July 23, 2015 Share Posted July 23, 2015 The documentation says: “As in RenderMan Shading Language, parameters to user functions are always passed by reference, so modifications in a user function affect the variable the function was called with”. Or, as the error log says, your function parameter is set as read/write. When you do `b * 5.0` in your code, what's happening is that a new temporary object is being created, which is similar to C/C++'s r-values, and it is not possible to pass such objects to reference parameters because they are not held by any variable. This doesn't apply to simple built-in types such as `int` and `float` which are passed by copy rather than reference for optimization purposes, so this is why the call to `fit()` doesn't trigger the error. Also, the functions built-in in VEX seem to be able to define read-only parameters, which would make your parameter valid if it was passed to the `slerp()` function in example. To fix this, you simply need to store your operation into a new variable such as `vector c = b * 5.0;` before passing it to your function. This shouldn't cause any performance penalty since the same amount of memory would have been allocated with your temporary object anyways. The only difference is that the variable `c` will be held in memory for longer instead of being deallocated just after being used. No big deal. 1 1 Quote Link to comment Share on other sites More sharing options...
ChristopherC Posted July 28, 2015 Share Posted July 28, 2015 Well, I have overlooked the 2nd part of the sentence that I've quoted from the documentation “You can force a shader parameter to be read-only by prefixing it with the const keyword.” So, much better for you would be to add the `const` keyword in front of your function parameters. Also, by rereading your code, I see that you are actually modifying (normalizing) the arguments `a_vec` and `b_vec`, which is probably not what you want, ie: void myFunction(vector v1) { v1 = normalize(v1); } vector a = set(99, 0, 0); myFunction(a); // a is now equal to [1, 0, 0]!! Quote Link to comment Share on other sites More sharing options...
fathom Posted July 28, 2015 Share Posted July 28, 2015 so if parms are passed as reference, you can't pass the result of a function call (read only). have a temp variable hold the result of your fit() call and then pass that to your function. see if that fixes things. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.