# Java3D Objekt skalieren per JSlider/JButton



## eksel (7. Dez 2013)

Hallo Leute, wieder einmal bräuchte ich wertvolle Tipps und Denkanstöße zu meinem Poblem 

Ich würde gerne mit Java3D ein Objekt mit einem Slider (oder wenn es leichter sein sollte mit Buttons) skalieren. Sprich es ist ein Fenster vorhanden, in welchem Rechts der 3D Bereich mit dem Objekt ist, und Links verschiedene Slider, die bei Betätigung bestimmte Teile des Objektes größer oder kleiner machen sollen. Ich weiß nicht so recht wie ich das Problem angehen soll. Habt ihr da einige Ideen?

Vielen Dank :toll:


----------



## Tiding (8. Dez 2013)

Nun, ich kenne mich jetzt nicht wirklich gut mit Java3D aus, aber da sollte es doch dann eigentlich auch eine Methode zum skallieren geben! ???:L
Ansonsten braucht es wohl eine Matrix, zum skallieren des Objektes.

Oder habe ich jetzt dein Problem nicht verstanden? :bloed:

Sprich, kennst du bereits eine Methode, die das gewünschte macht, oder brauchst du genau diese? 

lg


----------



## eksel (8. Dez 2013)

Also Methoden gibt es schon, ich meine setScale tut ja im Prinzip was ich möchte, nur weiß ich nicht ob setScale die richtige Wahl ist. Ich möchte ja per Slider (oder evtl. durch einen Buttonklick) ein Objekt größer oder kleiner skalieren. Neben setScale gibt es ja aber auch noch den ScaleInterpolator, dessen Funktion ich noch nicht ganz durchdrungen habe, deswegen stellt sich mir die Frage, was ich ganz genau nutzen sollte... :bahnhof:


----------



## Tiding (8. Dez 2013)

Ob Button oder Slider, das Objekt wird ja folglich in jedem "tick" (hier meine ich Buttonklick, oder Sliderstatusveränderung) um einen bestimmten Faktor, der vorher angegeben werden muss, verkleinert oder vergrößert. Da jeder "tick" ja visuell angezeigt wird, könnte das schon Rechenaufwendig sein.

Soviel wie ich jetzt zum ScaleInterpolator gelesen habe, ist das wohl zur Animationssteuerung gedacht. Eigentlich ist eine Animation zu zeigen, meiner Meinung nach, dann eher nicht so sinnvoll, da du im Hintergrund ja trotzdem "setScale" benutzen musst, um deine Werte zu erhalten, die du ja sicher brauchst!

Wenn du das Objekt nur aus Spass größer oder kleiner werden lassen willst und damit nichts weiter anfangen willst, es also nur der visuellen Freuden dienen soll, sprich eine Animation sein soll, würde ich wohl die Animation nehmen :bahnhof: .


Sprich ich würde das wie folgt umsetzen:
Ein Buttonklick: Bestimmten Scale-Wert (z.B. =110%; könnte man ja auch durch den Benutzer verändern lassen können.) nehmen und das Objekt vergrößern.
Und fertig.


----------



## eksel (8. Dez 2013)

Erstmal danke für die Hilfestellung. Es ist richtig wie du sagtest, es soll lediglich größer und kleiner gemacht werden, ohne Weiteres. Ich habe jetzt auch ein wenig rumgebastelt und deinen Gedanken (den ich auch von Anfang an hatte) halbwegs umgesetzt, sprich mit setScale gearbeitet. Dennoch wirft der mir ne Exception, wenn ich das Programm ausführe und den Button("test") klicke.

Die Exception ist folgende

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

und bezieht sich auf Zeile 10 
	
	
	
	





```
skaliereMerkmalPlus(universe);
```
 und Zeile 41 
	
	
	
	





```
oKopf.setScale(d);
```


Hier der relevante Codeausschnitt:


```
double d = 1;

        weitere Datenfelder, Kontruktor,... hier ausgelassen

    public void kopf() {

	    JButton test = new JButton("test");
		test.addActionListener(new ActionListener() {
			 public void actionPerformed(ActionEvent e) { 
				 skaliereMerkmalPlus(universe);
			}
		});
                
                ...
        }

	public void erzeugeSzenenGraph(SimpleUniverse su) {

		ObjectFile kopf = new ObjectFile(ObjectFile.RESIZE);
		Scene scene = null;
		try {
			scene = kopf.load("KopfM.obj");
		} catch (Exception e) {
			e.printStackTrace();
		}

		szene = new BranchGroup();

		TransformGroup tgSzene = new TransformGroup();
		tgSzene.addChild(scene.getSceneGroup());

		alleObjekte = scene.getNamedObjects();

		szene.addChild(tgSzene);
		szene.compile();
		su.addBranchGraph(szene);
	}

	public void skaliereMerkmalPlus(SimpleUniverse su) {
		Transform3D oKopf = (Transform3D) alleObjekte.get("Cube");
		oKopf.setScale(d);

		if (d <= 5 && d >= 0) {
			oKopf.setScale(d + 1);
			d = oKopf.getScale();
		} else {
			d = 6;
		}

		TransformGroup tgScale = new TransformGroup(oKopf);
	}
```


----------



## Tiding (8. Dez 2013)

Sicher, dass du das SimpleUniverse "universe" irgendwo initialisiert und instanziiert hast?


----------



## eksel (8. Dez 2013)

Jap, ganz sicher. Das Programm wird ja ausgeführt und es erscheint alles wie es soll, erst beim ButtonKlick komt die Fehlermeldung und es tut sich nichts weiteres :bahnhof:


----------



## Tiding (8. Dez 2013)

Dann eine andere Frage: (Entweder bin ich blind, oder übersehe was!)

Wozu brauchst du das universe überhaupt in der Methode skaliereMerkmalPlus() ?

Es würde Sinn machen, wenn du es irgendwo gebrauchen würdest


----------



## eksel (8. Dez 2013)

Emm, vielleicht liege ich da auch falsch, aber ich dachte ich muss die Veränderung durch den ButtonKlick an das SimpleUniverse übergeben, da sonst nichts passieren würde.

P.S.: habe eben auch ohne universe versucht auszuführen, es kommt wieder dieselbe Exception ;(


----------



## Tiding (8. Dez 2013)

das machst du da aber nicht ???:L

 und Zeile 41 
	
	
	
	





```
oKopf.setScale(d);
```
 ist mir gerade erst aufgefallen, dass da ja noch mehr steht  :bloed: also: Sicher, dass oKopf != null?

starte mal den debugger von Eclipse, da kann man sowas wunderbar nachschauen


----------



## eksel (9. Dez 2013)

Irgendwie bin ich jetzt veriwrrt, sry  Ich poste mal sicherheitshalber den kompletten Code, vielleicht wird dann einiges klarer...



```
......import ausgelassen.......

public class Modell {

	private JFrame fenster3;
	private Container contentPane3;
	private JPanel merkmale;
	private JLabel lAugen, lNase, lMund, lOhren;
	private JSlider sAugen, sNase, sMund, sOhren;

	private Canvas3D canvas;
	private SimpleUniverse universe;
	private BranchGroup szene, lichtBG;
	private Hashtable alleObjekte;

	double d = 1;

	public Modell() {
		modell();
	}

	public void modell() {

 		fenster3 = new JFrame("3D Modell");

 		contentPane3 = fenster3.getContentPane();
 		contentPane3.setLayout(new BorderLayout(0, 0));

 		canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
		contentPane3.add(BorderLayout.CENTER, canvas);

 		universe = new SimpleUniverse(canvas);
 		universe.getViewingPlatform().setNominalViewingTransform();

		erzeugeSzenenGraph(universe);
 		erzeugeLicht(universe);

 		OrbitBehavior ob = new OrbitBehavior(canvas);
		BoundingSphere bs = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
 		          Double.MAX_VALUE);
		ob.setTranslateEnable(false);
		ob.setSchedulingBounds(bs);
		ob.setRotFactors(1, 0);
		universe.getViewingPlatform().setViewPlatformBehavior(ob);

		merkmale = new JPanel();
 		merkmale.setLayout(new GridLayout(0, 1, 0, 0));
 		merkmale.setBackground(Color.LIGHT_GRAY);

		JButton testPlus = new JButton("testPlus");
		testPlus.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) { 
				skaliereMerkmalPlus();
			}
		});
		
		JButton testMinus = new JButton("testMinus");
		testMinus.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) { 
				skaliereMerkmalMinus(universe);
			}
		});
		
		merkmale.add(testPlus);
		merkmale.add(testMinus);
		
		
		// Hinzufügen des Panels zum westlichen Bereich des Fensters
		contentPane3.add(merkmale, BorderLayout.WEST);

		// Einstellungen des Fensters
		fenster3.setVisible(true);
		fenster3.setSize(1000, 700);
	}

	public void erzeugeSzenenGraph(SimpleUniverse su) {

		ObjectFile kopf = new ObjectFile(ObjectFile.RESIZE);
		Scene scene = null;
		try {
			scene = kopf.load("KopfM.obj");
		} catch (Exception e) {
			e.printStackTrace();
		}

		szene = new BranchGroup();

		TransformGroup tgSzene = new TransformGroup();
		tgSzene.addChild(scene.getSceneGroup());

		alleObjekte = scene.getNamedObjects();

		szene.addChild(tgSzene);
		szene.compile();
		su.addBranchGraph(szene);

	}
	
	
	public void skaliereMerkmalPlus() {
		Transform3D oKopf = (Transform3D) alleObjekte.get("Cube");
		oKopf.setScale(d);

		if (d <= 5 && d >= 1) {
			oKopf.setScale(d + 1);
			d = oKopf.getScale();
		} else {
			d = 5;
		}
	}
	
	public void skaliereMerkmalMinus(SimpleUniverse su) {
		Transform3D oKopf = (Transform3D) alleObjekte.get("Cube");
		oKopf.setScale(d);

		if (d <= 6 && d >= 1) {
			oKopf.setScale(d - 1);
			d = oKopf.getScale();
		} else {
			d = 1;
		}

		BranchGroup bgScale = new BranchGroup();
		TransformGroup tgScale = new TransformGroup(oKopf);
		bgScale.addChild(tgScale);
		su.addBranchGraph(bgScale);
	}
	

	public void erzeugeLicht(SimpleUniverse su) {
		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
				Double.MAX_VALUE);

		Color3f farbe = new Color3f(0.55f, 0.55f, 0.55f);

		AmbientLight aL1 = new AmbientLight(farbe);
		aL1.setInfluencingBounds(bounds);

		Vector3f v1 = new Vector3f(-20.0f, 5.0f, 0.0f);
		DirectionalLight dL1 = new DirectionalLight(farbe, v1);
		dL1.setInfluencingBounds(bounds);

		lichtBG = new BranchGroup();
		lichtBG.addChild(aL1);
		lichtBG.addChild(dL1);

		su.addBranchGraph(lichtBG);
	}

	public static void main(String[] args) {
		new Modell();
	}
}
```


----------

