|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 42
|
[JAVA3D] problema rotazione ambiente
salve, ho un problema che non riesco a risolvere, in pratica disegno un cubo che non è altro che tanti Box inseriti vicini e vorrei far ruotare il sistema però non ci riesco, posto il codice e spiego perchè:
Codice:
public class Cubo extends TransformGroup{
private Box box;
private static TextureLoader loader=new TextureLoader("red.jpg",null);
private static TextureLoader loader2=new TextureLoader("green.jpg",null);
public Cubo(float x, float y, float z){
super();
//System.out.println("CREA CUBO");
Transform3D transform = new Transform3D();
Vector3f vector = new Vector3f(x,y,z);
transform.setTranslation(vector);
setTransform(transform);
Appearance a = new Appearance();
a.setTexture(loader.getTexture());
TextureAttributes texAttr = new TextureAttributes();
texAttr.setTextureMode(TextureAttributes.MODULATE);
a.setTextureAttributes(texAttr);
/* Material mat = new Material();
mat.setDiffuseColor(new Color3f(1.0f, 0.0f, 0.0f));
//mat.setSpecularColor(new Color3f(1.0f, 0.0f, 0.0f));
mat.setShininess(1.0f);
a.setMaterial(mat);*/
box = new Box(0.1f, 0.1f, 0.1f, Box.GENERATE_TEXTURE_COORDS, a);
box.setAppearance(a);
addChild(box);
}
Codice:
class GruppoCubo extends TransformGroup{
//Memorizza puntatori alle matrici che contengono i cubi
private Vector<Cubo[][]> facce = null;
private int numCubiRiga = 0;
public GruppoCubo(int n, float x, float y, float z){
numCubiRiga = n;
Cubo[][] faccia = null;
float indiceZ = 0.0f; float indiceY = 0.0f; float indiceX = 0.0f;
int i = 0; int j = 0; //mi servono per calcolare gli indici dove salvare i cubi
while(indiceZ > (-n*0.23f)){
//System.out.println("indiceZ, n = " + (-n*0.1f) + " "+indiceZ);
i = 0; j = 0;
faccia = new Cubo[n][n];
while(indiceY > (-n*0.23f)){
//System.out.println("indiceY, n = "+ (-n*0.1f)+ " " + indiceY);
while(indiceX < (n*0.23f)){
//System.out.println("indiceX, n= " + (-n*0.1f)+" " + indiceX);
faccia[i][j] = new Cubo(indiceX, indiceY, indiceZ);
if(indiceX == 0.0f) (faccia[i][j]).coloraCubo(1);
addChild(faccia[i][j]);
indiceX = indiceX + 0.23f;
i += 1;
}
indiceX=0;
i=0; j = j+1;
indiceY = indiceY - 0.23f;
}
indiceY=0;
indiceZ = indiceZ -0.23f;
}
System.out.println("OUT");
Vector3f vector = null;
Transform3D transform = new Transform3D();
transform.setScale(1);
vector = new Vector3f(x,y,z);
transform.setTranslation(vector);
setTransform(transform);
setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
//Crea il behavior per ruotare il cubo
/* RotazioneCubo rc = new RotazioneCubo(/*cuboGrafico*///);
/* RotazioneMouse myMouseRotate2= new RotazioneMouse(this,rc);
myMouseRotate2.setSchedulingBounds(new BoundingSphere());
addChild(myMouseRotate2);*/
}
Codice:
public class DrawCubo extends SimpleUniverse{
private GruppoCubo cubo;
private BranchGroup root = null;
//Riceve come parametro il num elementi di una riga
public DrawCubo(int n, Canvas3D canvas){
super(canvas);
switch (n){
case 5: cubo = new GruppoCubo(n, 0f, 0.2f, -2f);
break;
case 10: cubo = new GruppoCubo(n, 0f, 0.1f, -10f);
break;
case 15: cubo = new GruppoCubo(n, 0f, -0.1f, -19f);
break;
case 7: cubo = new GruppoCubo(n, 0f, 0.2f, -5f);
break;
case 14: cubo = new GruppoCubo(n, 0f, 0.0f, -17f);
break;
case 21: cubo = new GruppoCubo(n, 0f, -0.2f, -29f);
break;
case 9: cubo = new GruppoCubo(n, 0f, 0.2f, -9f);
break;
case 18: cubo = new GruppoCubo(n, 0f, -0.15f, -24f);
break;
case 27: cubo = new GruppoCubo(n, 0f, -0.3f, -39f);
break;
}
root = new BranchGroup();
root.addChild(cubo);
getViewingPlatform().setNominalViewingTransform();
/*
TextureLoader loader=new TextureLoader("sfondo.jpg",null);
ImageComponent2D image=loader.getImage();
Background bg = new Background(image);
BoundingSphere infinity = new BoundingSphere(new Point3d(), Double.POSITIVE_INFINITY);
bg.setApplicationBounds(infinity);
root.addChild(bg);*/
//Crea un gruppo per le trasformazioni affini
TransformGroup objRotate=new TransformGroup();
objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
//Crea il behavior per ruotare il cubo
RotazioneCubo rc = new RotazioneCubo(/*cuboGrafico*/);
RotazioneMouse myMouseRotate2= new RotazioneMouse(objRotate,rc);
myMouseRotate2.setSchedulingBounds(new BoundingSphere());
root.addChild(myMouseRotate2);
root.addChild(objRotate);
root.compile();
addBranchGraph(root);
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Crea un TransformGroup "ruotabile" (setCapability eccetera), chiamiamolo A. Aggiungi al TransformGroup un BranchGroup, aggiungi tutti i cubi a questo BranchGroup.
A questo punto se fai ruotare "A" ruota anche tutto quello che è agganciato ad A. Il problema della rotazione intorno al centro lo risolvi o con una rototraslazione di A o con una rotazione semplice di A ed una distribuzione dei cubi attorno al centro di A. Per distribuire rapidamente i cubi puoi aggiungere ad A un secondo TransformGroup B, aggiungere i cubi a B e traslare B di un vettore V = (-x/2, -y/2, -z/2), con x, y e z lunghezze dei lati del "super-cubo" formato dai tanti cubetti. A conti fatti Java3D transformerà la faccenda in una rotazione di A intorno al punto P centro del gruppo di cubi.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 42
|
grazie mille adesso provo
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 42
|
ho fatto cosi però non cambia nulla:
Codice:
class GruppoCubo extends TransformGroup{
//Memorizza puntatori alle matrici che contengono i cubi
private Vector<Cubo[][]> facce = new Vector<Cubo[][]>();
private int numCubiRiga = 0;
public GruppoCubo(int n, float x, float y, float z){
numCubiRiga = n;
Cubo[][] faccia = null;
//Creo un BranchGroup dove attaccare i cubi
BranchGroup branch = new BranchGroup();
//Creo un nuovo TransformGroup B per la rotazione al centro
TransformGroup B = new TransformGroup();
float indiceZ = 0.0f; float indiceY = 0.0f; float indiceX = 0.0f;
int i = 0; int j = 0; //mi servono per calcolare gli indici dove salvare i cubi
while(indiceZ > (-n*0.23f)){
//System.out.println("indiceZ, n = " + (-n*0.1f) + " "+indiceZ);
i = 0; j = 0;
faccia = new Cubo[n][n];
while(indiceY > (-n*0.23f)){
//System.out.println("indiceY, n = "+ (-n*0.1f)+ " " + indiceY);
while(indiceX < (n*0.23f)){
//System.out.println("indiceX, n= " + (-n*0.1f)+" " + indiceX);
faccia[i][j] = new Cubo(indiceX, indiceY, indiceZ);
branch.addChild(faccia[i][j]);
indiceX = indiceX + 0.23f;
i += 1;
};
indiceX=0;
i=0; j = j+1;
indiceY = indiceY - 0.23f;
}
facce.add(faccia);
indiceY=0;
indiceZ = indiceZ -0.23f;
}
System.out.println("OUT");
B.addChild(branch);
Vector3f vector = null;
Transform3D transform = new Transform3D();
vector = new Vector3f((n*0.1f)/2,-(n*0.1f)/2,-(n*0.1f)/2);
transform.setTranslation(vector);
B.setTransform(transform);
transform = new Transform3D();
transform.setScale(1);
vector = new Vector3f(x,y,z);
transform.setTranslation(vector);
setTransform(transform);
setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
//Crea il behavior per ruotare il cubo
RotazioneCubo rc = new RotazioneCubo(/*cuboGrafico*/);
RotazioneMouse myMouseRotate2= new RotazioneMouse(this,rc);
myMouseRotate2.setSchedulingBounds(new BoundingSphere());
addChild(myMouseRotate2);
addChild(B);
Ultima modifica di Marbury : 14-02-2008 alle 22:46. |
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 42
|
non riesco a risolvere, non è che potresti darmi una mano? Grazie
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
La versione più semplice è quella in cui i cubi del gruppo di cubi sono creati e distribuiti intorno al punto 0,0,0. Detta "CubeGroup" la classe che dichiara questo cubo di cubi e "getGroup()" il metodo di CubeGroup che restituisce un javax.media.j3d.node a cui sono connessi i vari cubi, il programma è semplicemente:
Codice:
package cubi;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.mouse.*;
public class Main implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new Main());
}
public void run() {
final int CUBE_COUNT = 4;
final float CUBE_EDGE = 1;
/* Questo è il gruppo di trasformazione "ruotabile" con il mouse a cui
è aggiunto il gruppo di cubi */
TransformGroup cubeGroupRotator = new TransformGroup();
cubeGroupRotator.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
cubeGroupRotator.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
/* Genero il cubo di cubi (distribuiti intorno al punto 0,0,0) e lo
aggiungo al gruppo di trasformazione "ruotabile" */
CubeGroup cubeGroup = new CubeGroup(CUBE_COUNT, CUBE_EDGE);
cubeGroupRotator.addChild(cubeGroup.getGroup());
BoundingSphere infinity = new BoundingSphere(new Point3d(), Double.POSITIVE_INFINITY);
MouseRotate rotator = new MouseRotate(cubeGroupRotator);
rotator.setSchedulingBounds(infinity);
/* Creo una radice per i miei elementi 3d... */
BranchGroup root = new BranchGroup();
/* Aggiungo alla radice il gruppo di rotazione (a cui è connesso il
cubo di cubi) */
root.addChild(cubeGroupRotator);
root.addChild(rotator);
/* Creo un canvas3d e un universo 3d, aggiungo all'universo la radice
della mia scena 3d e fine. */
Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
SimpleUniverse universe = new SimpleUniverse(canvas);
Transform3D viewTranslation = new Transform3D();
viewTranslation.setTranslation(new Vector3f(0, 0, 5 * CUBE_COUNT * CUBE_EDGE));
universe.getViewingPlatform().getViewPlatformTransform().setTransform(viewTranslation);
universe.addBranchGraph(root);
Frame window = new Frame("Test Cubi");
window.add(canvas);
window.setSize(400, 400);
window.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { System.exit(0); }
});
window.setVisible(true);
}
}
Codice:
package cubi;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
public class CubeGroup {
private BranchGroup group = new BranchGroup();
private final float EDGE;
private final int CUBE_COUNT;
public CubeGroup(int cubeCount, float cubeEdge) {
/* Genera un cubo di cubeCount cubi, ognuno di lato cubeEdge. I cubi sono
distribuiti intorno al punto (0,0,0). */
EDGE = cubeEdge;
CUBE_COUNT = cubeCount;
float groupEdge = 2.1f * CUBE_COUNT * EDGE;
float offset = groupEdge / 2 - EDGE;
for(int x = 0; x < cubeCount; x++) {
for(int y = 0; y < cubeCount; y++) {
for(int z = 0; z < cubeCount; z++) {
Appearance appearance = new Appearance();
Material material = new Material();
Color3f color = new Color3f(x / (float)CUBE_COUNT, y / (float)CUBE_COUNT, z / (float)CUBE_COUNT);
material.setEmissiveColor(color);
appearance.setMaterial(material);
Box box = new Box(EDGE, EDGE, EDGE, appearance);
Transform3D transform = new Transform3D();
Vector3f translation = new Vector3f(offset - 2.1f * x, offset - 2.1f * y, offset - 2.1f * z);
transform.setTranslation(translation);
TransformGroup boxLocator = new TransformGroup(transform);
boxLocator.addChild(box);
group.addChild(boxLocator);
}
}
}
group.compile();
}
public BranchGroup getGroup() {
return group;
}
}
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 42
|
grazie mille!
Ormai che ci sei volevo chiederti ancora una cosa: se provo a creare un cubo di 27*27 quindi 27*27 cubi, si pappa tutto lo heap. E' un problema di come li ho implementati e cioè uno per transformGroup?? Grazie ancora. edit: secondo te è fattibile fare in modo che se uno clicca su un cubo poi può trascinare tutta la "sfoglia" all'esterno, cliccare su uno dei cubi e rimetterla "al suo posto"? |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Prova ad aumentare la dimensione dell'heap. Per farlo quando lanci il programma da console aggiungi l'opzione -Xmx seguita dal numero di megabyte che pensi ti servano. Ad esempio per dare in pasto alla JVM fino a 512 megabyte di RAM:
java -Xmx512m ...eccetera Se ritieni che la dimensione massima dell'heap sia interamente necessaria puoi usare anche l'opzione -Xms che definisce la dimensione iniziale dell'heap. Ad esempio: java -Xmx512m -Xms512m ...eccetera In questo caso stabilisci che la JVM possa usare al massimo 512 megabyte di ram e che tutti e 512 i megabyte siano riservati già all'avvio. E' senz'altro possibile aggiungere il tipo di interazione che desideri ed esistono una varietà di modi per realizzarla. Uno di questi modi è usare un TransformGroup per ogni cubetto - vale a dire aggiungere il cubetto ad un TransformGroup ed aggiungere il TransformGroup al gruppo del super-cubo. Il gruppo di trasformazione opportunamente abilitato ti permette di spostare il cubetto, il resto è una questione di "picking" e collegamento tra il movimento del mouse e lo spostamento del cubo correntemente selezionato.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 07:45.



















