Multiple copy of a shape3D

Hey Guys…!!!
if i need to make multiple copy of a shape3D object…then how can i do that?? For example…if there is an shape 3D object Sphere and i want to make 20 copies of that object then what should i do…??? is there any method in Xith ,which can help me…
plzzz let me know…

I guess, you’re talking about displaying one Shape3D multiple times in a scene, aren’t you?

If you want to do so, then Links and SharedGroups are your friends. The Shape must be put into an instance of SharedGroup and this can be put into any number og Link instances.


Shape3D shape = new Shape3D(); ....
SharedGroup sg = new SharedGroup();
sg.addChild( shape );

Link link1 = new Links( sg );
anyGroupABC1.addChild( link1 );

Link link2 = new Links( sg );
anyGroupABC2.addChild( link2 );

Link link3 = new Links( sg );
anyGroupABC3.addChild( link3 );

If you were talking about actually copying the shapes, then you’ll have to do it by hand, since the close methods don’t work so far. But it’s not too heavy. You can even reuse the Geometry, Appearance, Meterial, etc. instances.

Hope, this helps you :slight_smile:

Marvin

Welcome back, mksingh1! So you using Xith? Cool! 8)

You mean the “clone” methods ? No use ! It’s rubbish to use clone() anyway (well that’s what I found out, having tried to). sharedCopy() works very well, if you want a real copy then… there are some, can’t remember which (if you’re interested let me know).
Just as a side-note : shared copies use less memory and are faster to make. Links are even better.

thanks Wenger… :slight_smile:
as you have mentioned that if i want to make real copies,then there are some methods in Xith,which can help…
actually i didn’t get the idea of “real” copies…can u plz tell what does you mean by REAL copiesand what are the methods to create them…

sorry I didn’t explained acceptably.

So our scenegraph is acyclic. That does mean that nodes can’t have more than one parents (that is, they cannot be added twice, cannot exists in two places of the scenegraph).

So you can not just make :


Shape3D sphere = new Sphere(10, 10, 2f); // Create a sphere with a radius of 2f, and a precision of 10
// Add 20 spheres
for(int i = 0; i < 20; i++) {
  scene.addChild((new Transform(model)).setTranslationX(model)); // ILLEGAL ! Shape added more than once
}

However, what you can make is to clone the Shape3D


Shape3D sphere = new Sphere(10, 10, 2f); // Create a sphere with a radius of 2f, and a precision of 10
// Add 20 spheres
for(int i = 0; i < 20; i++) {
  scene.addChild((new Transform((Shape3D)model.clone())).setTranslationX(model)); // Notice the clone() method
}

This makes a “real” copy of the shape, which means everything is copied (Shape3D, Appearance, Material, all Attributes, + Geometry, all vertex data, texture UV, and so on).
This is bad from a memory and loading time / run time point of view, because all data is duplicated.

What you can do to reduce memory usage and load/run time is to make shared copies :


Shape3D sphere = new Sphere(10, 10, 2f); // Create a sphere with a radius of 2f, and a precision of 10
// Add 20 spheres
for(int i = 0; i < 20; i++) {
  scene.addChild((new Transform((Shape3D)model.sharedCopy())).setTranslationX(model)); // Notice the sharedCopy() method
}

This won’t copy e.g. vertex data, UV, but just creates a new Shape3D and assign the same Material & Appearance objects.

Even better is creating links :


Shape3D sphere = new Sphere(10, 10, 2f); // Create a sphere with a radius of 2f, and a precision of 10
SharedGroup sg = new SharedGroup(); // Shared group creation
sg.addChild(sphere); // Add the sphere to the shared group
// Add 20 spheres
for(int i = 0; i < 20; i++) {
  Link l = new Link(sg);
  scene.addChild((new Transform(l).setTranslationX(model)); // Notice the clone() method
}

In this case, the Link points to a SharedGroup which can be rendered any number of times. The benefit is that no duplicate Shape3D objects are created, just links… and anything can be added to Links…

A last thing : beware of shared copies : if you change something in the geometry of one it will change every other… but it’s probably not a problem.

I hope you got my point, if it was clear enough I’ll make a code example in W3G for that…

Well, only one SharedGroup can be set to a Link ;D. Anything can be added to a SharedGroup ;).

In most cases you’ll want to add only one Node (a model, etc…) to a SharedGroup. I’ve just created a convenience constructor to make this:


SharedGroup sg = new SharedGroup();
sg.addChild( myModel );

possible in one line:


SharedGroup sg = new SharedGroup( myModel );

I think it could be worthy :).

Marvin

Thanks Wenger…thanks for sharing your knowledge with me…its reall gonna help me alot… :slight_smile:

i know i m being greedy… :wink: but i m very new into this…so plzzzzzz…

if i have copied any shape3D object and now i want to paste it on mouseclick position,then how i can u do it…n i dont want to delete the original copy…its like normal copy-paste functionality…
for ex- i have copied a rectangle and now i want to paste it on mouseclick position ,then how can i do it???

Have a look at org.xith3d.picking.PickRay
It creates a ray from canvas coordiantes to world coordinates starting at the mouse position and points ortogonally into the depth. You just need to set the depth component and you’ll have the 3d-coordinate in space.

Marvin

So I assume you infact work on a 2D plane.

When working with a mouse in 3D, you must understand that your mouse position (point : x,y) on your 2D screen is infact a ray in your 3D world (x,y,z). So if you want to restrict your objects to a plane, then you can do picking on a specific plane…

Just create a plane for example if your “up” vector is +Z do :


Quad workPlane = new Quad(80000f, 80000f);
BranchGroup pickable = new BranchGroup();
pickable.add(workPlane);


Shape shape = new Sphere(10, 10, 3f);


// When you want to add a copied shape
mouseReleased(int button, int x, int y) {
  PickResult pr = PickingLibrary.pickNearest(pickable, x, y);
  if(pr != null) {
    Transform t = (new Transform(shape)).setTranslation(pr.getPosition());
    scene.addChild(t);
  }
}

And that’s it !

Be aware, though, that this does not provide a way to remove them.

Well, keep in mind, that picking needs to be synchronized with the rendering thread. That can be done by wrapping the pikcing code with


synchronized ( env.getUniverse() )
{
    // your picking code...
}

or scheduled with


env.pick*(...);

Please refer to org.xith3d.test.picking.ScheduledPickingTest for exact syntax.

Marvin

Yeah, sure but I was assuming he did that in the loopIteration() method…