Skip to main content

addBranchGraph method doesn´t work

7 replies [Last post]
romanturbo
Offline
Joined: 2007-08-15
Points: 0

Hi!

I have a problem with the addBranchGraph method: It doesn´t work when my BranchGroup object is big, I mean, when my scene has about 100000 boxes.

My scene is created from a 3 dimensions boolean array. If an element of the array is true, then I add a box, with his TransformGroup object, to the BranchGroup object (root of the scene). Of course, I use the compile method to compile the BranchGroup object.

My program works when my scene has less boxes.

I tried to solve the problem by increasing the memory of the Java Virtual Machine, but it didn´t work.

Can anybody help me?

Thanks!

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mrmojo
Offline
Joined: 2007-08-21
Points: 0

Hi interactivemesh,

I have the same problem like romanturbo:

Windows XP, 2GB, JDK 1.5, Java 3D 1.5.

I already tried sharing my boxes and of course the app needs much less memory then not sharing the boxes.

But even when I inititialize my programm with 1024 MB memory I will get the out of memory exception.

I also tried it with 100.000 boxes. What do you mean by:

- vertex format = COORDINATES | NORMALS | BY_REFERENCE
- a single IndexedQuadArray shared by all Shape3Ds
- a single Appearance/Material shared by all Shape3Ds
- 100,000 TransformGroups, one for each Shape3D.

It would be very helpfull if you could outline your test program. I am very stack at the moment.

Many thanks.

interactivemesh
Offline
Joined: 2006-06-07
Points: 0

Hi mrmojo,

my test program is just a minimum scene graph that loads all these boxes and renders them into a Canvas3D. I set -Xmx to 1536m. You will find the test case in 'addBoxes(BranchGroup branchGroup, boolean ucio)' below.

Alternatively I created a single Shape3D based on a single geometry representing multiple boxes as well: 'addMultiBox(BranchGroup branchGroup, boolean ucio)'. That avoids all TransformGroups, reduces the memory load under 100MB, and increases FPS noticeably.

The option 'ucio' (USE_COORD_INDEX_ONLY) allows to find a faster kind of implementation. In this case there seem to be no relevant differences contrary to the results in http://forums.java.net/jive/thread.jspa?threadID=29835&tstart=0.

Even if I don't know what you are doing with 100,000 boxes: have fun!

August

[code]
// ucio: USE_COORD_INDEX_ONLY
private void addBoxes(BranchGroup branchGroup, boolean ucio) {

float[] coords = {
// front +Z
-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
// back -Z
0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
// right +X
0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
// left -X
-0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f,
// top +Y
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
// bottom -Y
-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f
};

float[] normals = {
// +Z
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
// -Z
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
// +X
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// -X
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
// +Y
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// -Y
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f
};

// Single shared QuadArray | IndexedQuadArray
GeometryArray boxGeometry = null;

if (ucio) {
int[] indices = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};

boxGeometry = new IndexedQuadArray(
24,
GeometryArray.COORDINATES | GeometryArray.NORMALS |
GeometryArray.BY_REFERENCE | GeometryArray.BY_REFERENCE_INDICES |
GeometryArray.USE_COORD_INDEX_ONLY,
24
);
((IndexedQuadArray)boxGeometry).setCoordIndicesRef(indices);
}
else {
boxGeometry = new QuadArray(
24,
GeometryArray.COORDINATES | GeometryArray.NORMALS |
GeometryArray.BY_REFERENCE
);
}

boxGeometry.setCoordRefFloat(coords);
boxGeometry.setNormalRefFloat(normals);

// Single shared Appearance/Material
Appearance boxAppearance = new Appearance();
Material material = new Material();
material.setDiffuseColor(0.0f, 1.0f, 0.0f);
material.setSpecularColor(0, 0, 0);
boxAppearance.setMaterial(material);

// Transformed boxes
TransformGroup tg = null;
Transform3D t3d = new Transform3D();
Vector3f translation = new Vector3f();

Shape3D box = null;

// 100 * 50 * 20 = 100,000 Boxes
for (int x=0; x < 100; x++) {
for (int y=0; y < 50; y++) {
for (int z=0; z < 20; z++) {

translation.set(2*x, 2*y, 2*z);
t3d.setTranslation(translation);

tg = new TransformGroup();
tg.setTransform(t3d);

box = new Shape3D(boxGeometry, boxAppearance);

tg.addChild(box);
branchGroup.addChild(tg);
}
}
}
}

// ucio: USE_COORD_INDEX_ONLY
private void addMultiBox(BranchGroup branchGroup, boolean ucio) {

float[] baseCoords = {
// front +Z
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// back -Z
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
// right +X
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
// left -X
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// top +Y
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// bottom -Y
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f
};

float[] baseNormals = {
// +Z
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
// -Z
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
// +X
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// -X
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
// +Y
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// -Y
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f
};

// 100,000 Boxes
int boxCount = 100000;

float[] coords = new float[24 * 3 * boxCount];
float[] normals = new float[24 * 3 * boxCount];

int c = 0;
int n = 0;
// 100 * 50 * 20 = 100,000 Boxes
for (int x=0; x < 100; x++) {
for (int y=0; y < 50; y++) {
for (int z=0; z < 20; z++) {

for (int i=0,length=24*3; i < length; i+=3) {
coords[c++] = baseCoords[i] + 2*x;
coords[c++] = baseCoords[i+1] + 2*y;
coords[c++] = baseCoords[i+2] + 2*z;
}

for (int i=0,length=24*3; i < length; i+=3) {
normals[n++] = baseNormals[i];
normals[n++] = baseNormals[i+1];
normals[n++] = baseNormals[i+2];
}
}
}
}

// Single QuadArray | IndexedQuadArray
GeometryArray boxGeometry = null;

if (ucio) {
int[] indices = new int[24 * boxCount];
for (int i=0,length=24*boxCount; i < length; i++)
indices[i] = i;

boxGeometry = new IndexedQuadArray(
24 * boxCount,
GeometryArray.COORDINATES | GeometryArray.NORMALS |
GeometryArray.BY_REFERENCE | GeometryArray.BY_REFERENCE_INDICES |
GeometryArray.USE_COORD_INDEX_ONLY,
24 * boxCount
);
((IndexedQuadArray)boxGeometry).setCoordIndicesRef(indices);
}
else {
boxGeometry = new QuadArray(
24 * boxCount,
GeometryArray.COORDINATES | GeometryArray.NORMALS |
GeometryArray.BY_REFERENCE
);
}

boxGeometry.setCoordRefFloat(coords);
boxGeometry.setNormalRefFloat(normals);

// Single Appearance/Material
Appearance boxAppearance = new Appearance();
Material material = new Material();
material.setDiffuseColor(0.0f, 1.0f, 0.0f);
material.setSpecularColor(0, 0, 0);
boxAppearance.setMaterial(material);

// Single Shape3D
Shape3D box = new Shape3D(boxGeometry, boxAppearance);

branchGroup.addChild(box);
}
[/code]

jada
Offline
Joined: 2004-03-17
Points: 0

What is your system configuration, ie. OS, memory, Java and Java 3D version ?
Do you have a test program ? What doesn't work ? OOM ?

- Chien

romanturbo
Offline
Joined: 2007-08-15
Points: 0

Windows XP, 512MB, JDK 1.5, Java 3D 1.5.

While the addBranchGraph method is executing, it is thrown an exception:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

interactivemesh
Offline
Joined: 2006-06-07
Points: 0

Hi,

a simple test program of mine that renders 100,000 Shape3Ds/Boxes requires 485MB RAM in case of

- vertex format = COORDINATES | NORMALS | BY_REFERENCE
- a single IndexedQuadArray shared by all Shape3Ds
- a single Appearance/Material shared by all Shape3Ds
- 100,000 TransformGroups, one for each Shape3D.

Unfortunately too much for a 500MB RAM CPU.

August

romanturbo
Offline
Joined: 2007-08-15
Points: 0

Thank you very much, I´ll try in another computer

Dmitri Darine

It is very depending on your goal, but you could try to use textures
with alpha channel instead of boxes. For example, if you have 10x10x10
boolean array you need 3 perpendicular to each other stacks of 11
textures to "emulate" the boxes. These stacks intersect each other
forming the grid of boxes. To draw a box you need to set transparency of
6 corresponding pixels of 6 corresponding textures to 0 (opaque) -
forming the faces of the box.

Texture3D class can also be used.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net