DzInstance vs DzInstanceGroupNode

Hi,

I'm struggling with an issue I just really cannot find a good solution to.
I grab the WS data for DzInstances, and create a new Node by coping the DzInstance "parent" and it works like a charm, but, when the instance is an DzInstanceGroupNode inside a DzInstanceGroup populated by UltraScatter, the WS data is "offet" to the center of the parent node by the radius of the Object.


See the attached images, anyone have a good "You forgot to.." anwer to this?

The "objects ceated" are set to white shader.

 

Iotestreport.jpg
1200 x 600 - 110K
USRresult.jpg
1200 x 600 - 108K

Comments

  • rbtwhizrbtwhiz Posts: 2,250
    edited April 2018

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    Post edited by rbtwhiz on
  • TotteTotte Posts: 13,983
    rbtwhiz said:

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    The goal is to "uninstanciate them" so they can be exported in a export to obj or fbx.

     

  • BradCarstenBradCarsten Posts: 856
    edited April 2018

    Totte, I had the same problem on a script that I am working on. UltraScatter (or InstanceGroups) seems to set all the individual Origins to the same point - ie the center of the parent object. So have you tried running through the list of instances, and resetting each origin to its xyz position using DzNode.setOrign? 

    Post edited by BradCarsten on
  • TotteTotte Posts: 13,983
    bradrg said:

    Totte, If it's just the origins that are off. Can't you run through the list of instances, resetting each origin to the object's xyz position? 

    Hi, thanks, but origins are centered, it's the world space informaton (position, rotation anc scale) that when applied to a "real" object doesn't match.

    I grab the world space information from the instances, and "put that" into copies of the object the instance is an instance of, and I still get that "offset", so what I wonder is really why is the world space coordinates of an instance in an instance group not matching the real world space coordinates? There must be something I miss, some transformation that needs to be done when the instance is inside an instance group, but I've failed to find anything about that. 

    It's as you see only when it's inside instance groups this happens.

  • BradCarstenBradCarsten Posts: 856
    edited April 2018

    I've got a similar script as part of a program that I've recently submitted to the store, and I just tried it now, converting the objects from UltraScatter to objects and it keeps their positions perfectly, so at least we can rule out UltraScatter or Instance Groups as the culprit. There is something that I noticed though - the instances are grouped to the parent object, so if that parent object has a scale other than 100, the children will also be scaled slightly, which can throw the calculations off. 

    if it's not that, we may have to dig a bit deeper into the code itself. 

    Untitled-1.jpg
    912 x 676 - 297K
    Untitled-2.jpg
    912 x 676 - 292K
    Post edited by BradCarsten on
  • BradCarstenBradCarsten Posts: 856
    Totte said:
    bradrg said:

    Totte, If it's just the origins that are off. Can't you run through the list of instances, resetting each origin to the object's xyz position? 

    Hi, thanks, but origins are centered

    Wait, I may be misunderstanding you, but when you say the origins are centered, shouldn't they rather be set to the base of the instances, rather than the center? if they're centered that will explain why they are have dropped down like that. 

  • TotteTotte Posts: 13,983
    edited April 2018

    Hi!

    I just tested one of the ones I have and there are to spheres on that one (Got the scene from the one who found the issue):

    Contains two built in spheres, both are Ultrascattered, one of them has the origin centered (that one slips), the otherone has the origin center-bottom, that one works.
    So, you're onto something, it depends on if the sphere was created with Object Center or World Center.
    Hmm, wonder if that is stored somewhere in the Node data...

    As you see the "blue" is decoded correctly while pink fails.

     



     

    weird.jpg
    700 x 745 - 42K
    center.jpg
    335 x 219 - 4K
    Post edited by Totte on
  • BradCarstenBradCarsten Posts: 856
    edited April 2018

     

    Here's the code I used to convert from Instance to Object. Perhaps it'll help. Duplicating the target node should preserve the Origin data. it's then just up to you to rename the object and move it into position.

    oTargetNode is the original node.

    oNode is the duplicate of it.

    oSelectedNode is the instance that you want to replace. 

    var oTargetNode=oSelectedNode.getTarget();var oNode=oTargetNode.duplicate(false);oNode.setName(GetUniqueName(oTargetNode.objectName));	oNode.setLabel(GetUniqueLabel(oTargetNode.getLabel()));	oNode.setWSPos(oSelectedNode.getWSPos());oNode.setWSRot(oSelectedNode.getWSRot());oNode.setWSScale(oSelectedNode.getWSScale());

     

    Post edited by BradCarsten on
  • TotteTotte Posts: 13,983

     

     



     

    bradrg said:

     

    Here's the code I used to convert from Instance to Object. Perhaps it'll help. Duplicating the target node should preserve the Origin data. it's then just up to you to rename the object and move it into position.

    oTargetNode is the original node.

    oNode is the duplicate of it.

    oSelectedNode is the instance that you want to replace. 

    var oTargetNode=oSelectedNode.getTarget();var oNode=oTargetNode.duplicate(false);oNode.setName(GetUniqueName(oTargetNode.objectName));	oNode.setLabel(GetUniqueLabel(oTargetNode.getLabel()));	oNode.setWSPos(oSelectedNode.getWSPos());oNode.setWSRot(oSelectedNode.getWSRot());oNode.setWSScale(oSelectedNode.getWSScale());

     

    I use pretty much the same code, but the issue seems to be when the object instantiated is set to Object center (thanks for that hint, never thought of that), so I'm working on code to identify that and handle it, gonna run some tests soon.

    Cheers!

     

  • BradCarstenBradCarsten Posts: 856
    Totte said:

     

     



     

    bradrg said:

     

    Here's the code I used to convert from Instance to Object. Perhaps it'll help. Duplicating the target node should preserve the Origin data. it's then just up to you to rename the object and move it into position.

    oTargetNode is the original node.

    oNode is the duplicate of it.

    oSelectedNode is the instance that you want to replace. 

    var oTargetNode=oSelectedNode.getTarget();var oNode=oTargetNode.duplicate(false);oNode.setName(GetUniqueName(oTargetNode.objectName));	oNode.setLabel(GetUniqueLabel(oTargetNode.getLabel()));	oNode.setWSPos(oSelectedNode.getWSPos());oNode.setWSRot(oSelectedNode.getWSRot());oNode.setWSScale(oSelectedNode.getWSScale());

     

    I use pretty much the same code, but the issue seems to be when the object instantiated is set to Object center (thanks for that hint, never thought of that), so I'm working on code to identify that and handle it, gonna run some tests soon.

    Cheers!

     

    Intersting. What causes that? Is that something that UltraScatter does? 

  • TotteTotte Posts: 13,983
    bradrg said:
    Totte said:

     

     



     

    bradrg said:

     

    Here's the code I used to convert from Instance to Object. Perhaps it'll help. Duplicating the target node should preserve the Origin data. it's then just up to you to rename the object and move it into position.

    oTargetNode is the original node.

    oNode is the duplicate of it.

    oSelectedNode is the instance that you want to replace. 

    var oTargetNode=oSelectedNode.getTarget();var oNode=oTargetNode.duplicate(false);oNode.setName(GetUniqueName(oTargetNode.objectName));	oNode.setLabel(GetUniqueLabel(oTargetNode.getLabel()));	oNode.setWSPos(oSelectedNode.getWSPos());oNode.setWSRot(oSelectedNode.getWSRot());oNode.setWSScale(oSelectedNode.getWSScale());

     

    I use pretty much the same code, but the issue seems to be when the object instantiated is set to Object center (thanks for that hint, never thought of that), so I'm working on code to identify that and handle it, gonna run some tests soon.

    Cheers!

     

    Intersting. What causes that? Is that something that UltraScatter does? 

    Nope, when you create a built in sphere, there is a popup (World Space or Object Space), and the test case I got had one sphere as World Space and one as Object Space, I guess that was sheer coincidence (or the one reporting is more sinister than I imagine ;-))

    One thing: Your code wont handle when and object is a child of an object that is a child of an object and then you run UltraScatter on that object tree it looks like (you don't copy deep) when you copy the node. 

     

  • TotteTotte Posts: 13,983

    So now I need to find a way to see if the origin is not WorldSpace... 

  • TotteTotte Posts: 13,983
    edited April 2018

    I found that for the World Space Sphere, origin i is 0,0,0, fot the other it's 0,<half height>, 0, which is corerct, so I know which object that does have origin at center bottom, now just figure out how to transform that correctly as it might be scaled and rotated too... What a can of worms ;-)

    Post edited by Totte on
  • TotteTotte Posts: 13,983
    if (oNewNode.getOrigin(true).y != 0 ) {oNewNode.setOrigin(new DzVec3(0,0,0), true);}

    Seems to do the trick!

  • BradCarstenBradCarsten Posts: 856

    Ah, I understand the problem. good find. Wow, it never ceases to amaze me how easily users can find a way to break a program. haha Who would have thought to look at object space and world space. I just wonder what else is lurking in there. 

  • TotteTotte Posts: 13,983

    *Indiana Jones theme music playing*
    '"I just wonder what else is lurking in there. "
    Opens and looks , "Snakes! why does ot have to be snakes??"

    I just found that it works in all cases, except when UltraScatter scatters adjusted to origin and origin is in local space (center), and the objects are supposed to be half way down into the scatter target, then I should not compensate for origin. I need to fins a way to "figure that one out" now. All other test cases works.

     

     

  • Alessandro MastronardiAlessandro Mastronardi Posts: 2,621
    edited August 2023

    rbtwhiz said:

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    Hi Rob, I did a few more experiments with the DzInstanceGroupNode and DzInstanceGroupItem. I fail to see how they could speed up things, given that you have to first create and add instances to the scene anyway (before creating a group item and a group node), and that it's very slow if you go over a 1000 instances, even using C++ and the SDK. Is this how it is, or am I missing something? Thanks

    Post edited by Alessandro Mastronardi on
  • TotteTotte Posts: 13,983

    Alessandro Mastronardi said:

    rbtwhiz said:

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    Hi Rob, I did a few more experiments with the DzInstanceGroupNode and DzInstanceGroupItem. I fail to see how they could speed up things, given that you have to first create and add instances to the scene anyway (before creating a group item and a group node), and that it's very slow if you go over a 1000 instances, even using C++ and the SDK. Is this how it is, or am I missing something? Thanks

    That's why you only add 999 DzGroupNodeItems / DzGroupNode, and have a shitload of DzGroupNodes

     

  • Totte said:

    Alessandro Mastronardi said:

    rbtwhiz said:

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    Hi Rob, I did a few more experiments with the DzInstanceGroupNode and DzInstanceGroupItem. I fail to see how they could speed up things, given that you have to first create and add instances to the scene anyway (before creating a group item and a group node), and that it's very slow if you go over a 1000 instances, even using C++ and the SDK. Is this how it is, or am I missing something? Thanks

    That's why you only add 999 DzGroupNodeItems / DzGroupNode, and have a shitload of DzGroupNodes

     

    Yes thanks Totte, I was aware of that. Still it takes 10-11 seconds to add each 999's strip. I hoped there was a way to go even faster.

  • TotteTotte Posts: 13,983

    Should not take that long, you need set it in edit mode, to avoid updating scene while inserting, but I agree, it does take time, and yea, I've only used them from Script, not Plugin/C++ which should be faster.
     

  • Alessandro Mastronardi said:

    Totte said:

    Alessandro Mastronardi said:

    rbtwhiz said:

    ​​DzInstanceNode inherits DzNode, which means it has all of the capabilities of a DzNode, plus some capabilities of its own. DzInstanceGroupNode inherits DzInstanceNode, which likewise means it has all of the capabilites of a DzInstanceNode (including the capabilites inherited from DzNode), plus some capabilities of its own. The purpose of DzInstanceNode is to "lighten the load" (consume less resources) by reusing data that has already been calculated for another object in the scene; it has its own transforms, but it doesn't need to do things in the geometry pipeline like apply modifiers (skining, morphs, smooting, push, etc.) or process materials, and so consumes considerably less resources during an update. The purpose of DzInstanceGroupNode is to "lighten the load" even further (consume even less resources) by consolidating the weight of multiple DzNode instances down to the weight of a single DzNode instance. It does this by converting DzInstanceNode instances into DzInstanceGroupItem instances and treating the entire group as a single DzNode instance. If your goal is to simply "group" DzInstanceNode instances, you could use a DzGroupNode instead.

    -Rob

    Hi Rob, I did a few more experiments with the DzInstanceGroupNode and DzInstanceGroupItem. I fail to see how they could speed up things, given that you have to first create and add instances to the scene anyway (before creating a group item and a group node), and that it's very slow if you go over a 1000 instances, even using C++ and the SDK. Is this how it is, or am I missing something? Thanks

    That's why you only add 999 DzGroupNodeItems / DzGroupNode, and have a shitload of DzGroupNodes

     

    Yes thanks Totte, I was aware of that. Still it takes 10-11 seconds to add each 999's strip. I hoped there was a way to go even faster.

    Yeah, in my C++ projects I don't think I go over 1000 instances per DzInstanceGroupNode - seems to stay quicker that way despite sometimes needing to make 100s of DzInstanceGroupNodes. But it should be nearly instantaneous - in UltraSceneryXT all the instances are created after you hit render and takes only a second or 2 even for 100,000s of instances (most of the time is taken deciding where to place the instances).

    Interestingly, how long it takes to delete a DzInstanceGroupNode seems to go up exponentially with how many instances are within it, unless... you child all the DzInstanceGroupNodes to another group then delete the parent. Then poof - they're gone instantly.

Sign In or Register to comment.