Open azakhary opened 8 years ago
( So yeah I tried that, and it crashes as predicted :-P )
Maya was written originally with the location of each object being the name of each object in the hierarchy.
This meant that writing scripts that transformed hierarchies was really difficult! So bravo on all items having IDs. (What I learned from working in visual effects.)
The problem I can see is that you are trying to keep "instances" in sync, when they should be referential copies.
When you copy a library item, it should simply be :
libary_item
+ cat
+ hat
instance_of(library_item)
instance_of(library_item)
rather than:
library_item1
+ hat1
+ cat1
library_item2
+ hat2
+ cat2
Editing either item should edit the original, which is not stored in the scene. The instance_of is an object in its own right, with transforms.
Look at Libgdx's 3d meshbuilder for inspiration of how referentials can work. (A simple version of Maya DG)
If you want to do something complex like create three instances AND explode cat3 only, then you need to have operation histories which you can attach to instances.
i.e. operation1(operation2(instance_of(library_item))) Or rather operation1 -> operation2 -> instance_of -> library_item, indicating that other objects could connect as well.
Eventually this gets built out into a Dependency Graph. See Maya DG and Maya DAG, as this problem has been solved before in other contexts.
Hey, thanks a lot for the comment! I have to say that initially when designing this my idea was to have instances of library items just reference one item. Which would solve this. But when implementing I noticed that this makes problem after problem, like not "all parts" of item are part of library item (like coordinates), and who knows what else in future. So eventually I did it the way it is now, and, this appeared to be problematic as well, so I guess back to basics :))
But that would be a HUGE change to be honest. I am not sure how this can be implemented in less then a week or maybe more.
As for the Maya example, that's pretty cool, and thanks for sharing! I think I need to dive deeper into this, as I clearly they faced same problems. (Also the libgdx 3d meshbuilder)
No problem.
I don't see why it's not possible to support both models of operation, and let users decide which way they wish to edit objects. It would be a different kind of copy, and it wouldn't have to be feature complete when it starts. Anyway, something to think about :-)
This is just a thought experiment that I had, haven't actually checked, but I am almost positive this scenario is going to bug. So I will leave it here, if anyone is interested to know, or dive in.
Several things to know before I get to the reproducing. 1) Entity Modify Command is a kind of command that modifies an entity in any way (re-position or anything related), it is also extended from RevertableCommand, meaning it can be "undone". 2) If you delete an entity and then revert that, a new exact copy will be created, but it will be a different object in memory, meaning a revertible command cannot store entity references. The solution we have is, having uniqueId for each entity, so that when entity deletion is reverted, it get's same ID. And command stores id instead of reference, to re-do the action again. 3) When entity modify command happens, that not only means you changed one entity, but that also means you changed the parent entity of that entity in a way, logically. Thus, If it happens so that parent entity is an instance of "library item" it has to also change the library item, and also change all instances of that library item that are currently on the scene. To do that. Entity modify command, find all the "brother entities" of that parent. clears their content, and re-makes it from library that was just modified. This action unfortunately also re-assigns uniqueId values,a s the command had no idea what was exactly changed, it just knows that something was.
Now Knowing that we come to a theoretical bug that can happen with entity loosing it's Id's it will fail if it participated in chain of revertible commands. Here is how imho to reproduce that:
1) Create a composite out of 2 images, and add it to library. 2) Put a second copy on the scene, so now you have 2 identical composites, linked to one library item. 3) Enter into one of them, and add a second image to it 4) get out of composite, all should look identical, with 2 images in both composites. 5) Enter into the other composite, and say move an image, (this should result in uniqueId reset in other brother) 6) Get out to the root, and start Ctrl+Z-ing, at some point it will try to remove the "newly added second image" but it will not find it by Id, as the previous Id was reset. This probably will result in crash or to complete mess-up of Undo pipeline.
I am not really sure how to fix this, that is why I wrote this detailed issue description, so more experienced guys can help us out.
Best.