I learned a lot with you today. Thank you again!
Just one more question.
What did you mean when you sai this: Point3 x TM
For example, in my code, I have the modifier node.
How would I do that?
node->TM * what?
I’d want to know how to get the world-space when I have just the modifier node.
The TM of the node your modifier is on will already be in world space coordinates. In other words, if you query INode->GetObjectTM(TimeValue t) the resulting TM will be in world space coordinates.
However, the gizmo of your modifier is likely in local space coordinates. So if you query the gizmo for its TM and use that TM to make calculations for your strands, you’ll get incorrect behavior if the node the modifier is assigned to is not aligned to the world.
So what you want to do is convert the local TM of your modifier gizmo to a world coordinate system. You do this by multiplying it by the TM of the node the modifier is attached to.
I just mentioned Point3 x TM as an example of how to convert a Point3 value (a point in space) to a particular coordinate system.
Now I understand better!
I looked at the code and I think there is already that.
Please, see part of the code which create the gizmo:
GraphicsWindow *gw = vpt->getGW();
auto gtm = pblock->GetMatrix3(pb_sg_grav_dir,t); // pb_sg_grav_dir is a parameter which stores the gravity direction
auto tm = inode->GetObjectTM(t);
gw->setTransform(gtm * tm);
If ‘pb_sg_grav_dir’ is getting the gizmo transform and ‘inode’ is the node the modifier is applied to, then yes…gtm*tm will convert your gizmo transform to world coordinates.
But why are you setting the GraphicsWindow transform? I don’t get that part. Are the strands you’re displaying just viewport lines and not geometry?
Actually, that part of code is not about the strands, it’s about those orange lines you can see the figure I sent you last post, which are the gizmo (lines, rim and arrow).
Oh ok, then it’s fine, because the gizmo size coordinates are undoubtedly in local space and so that code is telling the GraphicsWindow the proper drawing space before sending the local coords.
So basically, take that same idea and apply it to the problem you’re having (get the world space transform of your gizmo and go from there)
I’ve already got the idea about world and local-space, but I still don’t know hot to do that in method MyModifier::Data::Apply.
It looks like the transformation in the sub-object code is aplied incorrectly… but I have no idea to fix that until now.
In MyModifier::Data::Apply, I tried lots of things like:
node->SetNodeTM(time, nodeTM * parentTM);
I just checked the code saw the method Rotate of the sub-object:
::Matrix3 mat;
val.MakeMatrix( mat ); // MyModifier::Rotate(Quat& val, …
auto gtm = pblock->GetMatrix3( pb_sg_grav_dir, t ) * mat;
pblock->SetValue( pb_sg_grav_dir, t, gtm );
I think the problem is here.
You keep posting snippets of code that don’t actually tell us what your plugin is supposed to do. Sorry, I can’t really help further beyond explaining again how coordinate space conversions work.
what is superclass of your plugin? (why do we have to compel these clear things from you?)
is it hard to tell: – it’s GeomObject (GEOMOBJECT_CLASS_ID)
maybe you don’t know but object and modifier plugins work in different coordinate systems internally.
well… in your case you have to do everything in the target node coordinate system.
but gizmo has to be in your object coordinate system.
so… world transform for gizmo result is yourObjTM * gizmoTM
in target space it will be (yourObjTM * gizmoTM) * (inverse targetTM)
for easier calculation just make your object always in world origin TM – Matrix3(1) and set origin gizmo TM to target’s TM