Java3D Sphere

W

Wishmaster51

Gast
Hallo,
Es geht um eine Aufgabe zu Java3D, die genaue Aufgabenstellung findet ihr in den Kommentaren.
Java:
import java.awt.Color;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;

/**
 * Aufgabe 9.5
 * <p>
 * Laden Sie den Coderahmen von der MMI-Übungsseite herunter. Er enthält den
 * Code für ein sehr einfaches Beispiel für Java3D, bietet aber schon
 * Interaktionsmöglichkeiten wie Rotieren (gedrückte linke Maustaste),
 * Verschieben (gedrückte rechte Maustaste) und Zoomen (Mausrad, mittlere
 * Maustaste bzw. linke Maustaste bei gedrückter Alt-Taste). Dargestellt wird
 * anfänglich das Standardobjekt ColorCube.
 * </p>
 * 
 * <p>
 * Ändern Sie die Anfangskonfiguration so, dass statt dem Würfel eine Kugel
 * gezeichnet wird. Die Kugel solle einen Radius von 1 und 500 Unterteilungen
 * besitzen. Setzen Sie den Parameter primflags auf den Wert
 * Sphere.GENERATE_NORMALS. Zusätzlich sollen für die Kugel
 * Materialeigenschaften Material mit folgenden Farben definiert werden.
 * Ambient: Blau, Eigenleuchten: Schwarz, Diffus: Blau, Glanzlicht: Weiß mit
 * Exponent 10:0.
 * </p>
 * 
 * <p>
 * Fügen Sie der Szene mehrere Lichtquellen hinzu: Eine ambiente Lichtquelle mit
 * der Farbe Grau, eine direktionale Lichtquelle mit der Farbe Weiß und der
 * Richtung (-1;-1;-0:1) sowie eine Punktlichtquelle mit der Farbe Grün, der
 * Position (-1;-1; 2) und der Dämpfung (0:1; 0:1; 0:3). Die resultierende Szene
 * sollte schließlich wie in Abbildung 3 aussehen.
 * </p>
 * 
 * Project: MMI_9<br />
 * Class: J3DFrame<br />
 * Date: 19.03.2012
 * 
 * @author xx
 */
public class J3DFrame extends JFrame
{
	private static final long serialVersionUID = 1L;
	private final Canvas3D canvas;
	private final SimpleUniverse universe;

	/**
	 * 
	 */
	public J3DFrame()
	{
		super("Java 3D");

		this.canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
		this.universe = new SimpleUniverse(this.canvas);

		final Transform3D stepBack = new Transform3D();
		stepBack.setTranslation(new Vector3d(0D, 0D, 5D));
		final Transform3D rotation = new Transform3D();
		rotation.setRotation(new AxisAngle4d(-1D, 1D, 0D, (30D * Math.PI) / 180D));

		final Transform3D viewTransform = new Transform3D();
		viewTransform.mul(rotation, stepBack);
		this.universe.getViewingPlatform().getMultiTransformGroup().getTransformGroup(0)
				.setTransform(viewTransform);

		final OrbitBehavior behavior = new OrbitBehavior(this.canvas);
		behavior.setSchedulingBounds(new BoundingSphere(new Point3d(0D, 0D, 0D), Double.MAX_VALUE));
		this.universe.getViewingPlatform().setViewPlatformBehavior(behavior);

		this.universe.addBranchGraph(createScene());

		this.getContentPane().add("Center", this.canvas);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(600, 400);
		this.setVisible(true);
	}

	/**
	 * Scene erzeugen
	 * 
	 * @return
	 */
	private static BranchGroup createScene()
	{

		final BranchGroup branchgroup = new BranchGroup();

		/*
		 * Ändern Sie an dieser Stelle den Code für Aufgabe 9.5
		 */
		final Material sphereMaterial = new Material();
		sphereMaterial.setAmbientColor(new Color3f(Color.BLUE));
		sphereMaterial.setEmissiveColor(new Color3f(Color.BLACK));
		sphereMaterial.setDiffuseColor(new Color3f(Color.BLUE));

		final Appearance sphereAppearance = new Appearance();
		sphereAppearance.setMaterial(sphereMaterial);

		final Transform3D sphereTransform = new Transform3D();
		final TransformGroup sphereTG = new TransformGroup(sphereTransform);
		//FIXME Wird nicht angezeigt
		sphereTG.addChild(new Sphere(1F, Primitive.GENERATE_NORMALS, 500, sphereAppearance));
		branchgroup.addChild(sphereTG);

		final AmbientLight aLight = new AmbientLight(true, new Color3f(Color.GRAY));
		branchgroup.addChild(aLight);

		final DirectionalLight dLight = new DirectionalLight(true, new Color3f(Color.WHITE),
				new Vector3f(-1F, -1F, -0.1F));
		branchgroup.addChild(dLight);

		final PointLight pLight = new PointLight(true, new Color3f(Color.GREEN), new Point3f(-1F,
				-1F, 2F), new Point3f(0.1F, 0.1F, 0.3F));
		branchgroup.addChild(pLight);

		return branchgroup;
	}

	@SuppressWarnings("unused")
	public static void main(final String args[])
	{
		new J3DFrame();
	}
}
Das Problem ist nun, dass der Bildschirm total schwarz bleibt :(

Mit dem vorgegebenen Beispiel, anstelle von Sphere einen ColorCobe zu zeichnen, wird dieser auch einwandfrei darggestellt, daher funktioniert Java3D prinzipiell schonmal bei mir.

Irgendeine Idee, weshalb dieser Sphere nicht gezeichnet wird? :(
 
Zuletzt bearbeitet von einem Moderator:

irgendjemand

Top Contributor
hab zwar kein J3D ... kanns daher nicht testen ... aber der code sieht echt wirr aus

1) zeile 140 : [c]@SuppressWarnings("unused")[/c] ??? warum das denn ?
2) zeile 104 : warum [c]static[/c] ?
3) nicht gerade OOP ... das setVisible() gehört NICHT in den konstruktor ... sondern in main() ... also eher so
Java:
J3DFrame frame=new J3DFrame();
frame.setVisible(true);
4) warum die ganzen [c]final[/c] ? das einzige was ich mir vorstellen könnte wäre um mutable objects zu schützen ... aber das macht in diesem beispiel keinen sinn ...

alles in allem ziemlich wirrer code mit ein paar zu vielen keywords ...

*wie gesagt : da ich kein J3D hab kann ich die funktion leider nicht testen*
 
W

Wishmaster51

Gast
Danke für die Antwort. Der Coderahmen als Ganzes war schon vorgegeben,im Wesentlichen habe ich nur an createScene rumgespielt.

1) Im Prinzip nur eine Compiler-Anweisung, um eine Warnung zu verhindern, weil das in main erzeugte Objekt nicht genutzt wird.
2) War im Prinzip auch so vorgegeben - welchen Sinn hätte es denn, das als Klassenmethode zu deklarieren? Weil im Prinzip greift der Code nirgens auf Klassenvariablen zu, und kann daher als static deklariert werden.
3) Ja, das ist wohl sinnvoll.
4) Naja, diese verwende ich eigendlich immer dann, wenn ich eine Variable nicht mehr überschreiben möchte, spricht irgendwas dagegen?
 

Marco13

Top Contributor
@irgendjemand: Manche Leute bezeichnen es als "guten Stil", alles final zu machen, was final sein kann. Ich finde das bei lokalen Variablen i.a. auch übertrieben, aber bei fields mache ich das auch. Genauso wie man private Methoden static machen sollte, wenn sie static sein können. Der Rest... Details.

@Wishmaster51: Bei beiden Lights noch was wie
pLight.setInfluencingBounds(new BoundingSphere(new Point3d(0D, 0D, 0D), 100));
 
W

Wishmaster51

Gast
@Wishmaster51: Bei beiden Lights noch was wie
pLight.setInfluencingBounds(new BoundingSphere(new Point3d(0D, 0D, 0D), 100));
Danke, das hilft, es sieht nun fast so aus wie in meiner Skizze.

Hier nochmal der Code, ich kann den oben irgendwie nicht mehr editieren:
Java:
import java.awt.Color;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;

/**
 * Aufgabe 9.5
 * <p>
 * Laden Sie den Coderahmen von der MMI-Übungsseite herunter. Er enthält den
 * Code für ein sehr einfaches Beispiel für Java3D, bietet aber schon
 * Interaktionsmöglichkeiten wie Rotieren (gedrückte linke Maustaste),
 * Verschieben (gedrückte rechte Maustaste) und Zoomen (Mausrad, mittlere
 * Maustaste bzw. linke Maustaste bei gedrückter Alt-Taste). Dargestellt wird
 * anfänglich das Standardobjekt ColorCube.
 * </p>
 * 
 * <p>
 * Ändern Sie die Anfangskonfiguration so, dass statt dem Würfel eine Kugel
 * gezeichnet wird. Die Kugel solle einen Radius von 1 und 500 Unterteilungen
 * besitzen. Setzen Sie den Parameter primflags auf den Wert
 * Sphere.GENERATE_NORMALS. Zusätzlich sollen für die Kugel
 * Materialeigenschaften Material mit folgenden Farben definiert werden.
 * Ambient: Blau, Eigenleuchten: Schwarz, Diffus: Blau, Glanzlicht: Weiß mit
 * Exponent 10:0.
 * </p>
 * 
 * <p>
 * Fügen Sie der Szene mehrere Lichtquellen hinzu: Eine ambiente Lichtquelle mit
 * der Farbe Grau, eine direktionale Lichtquelle mit der Farbe Weiß und der
 * Richtung (-1,-1,-0.1) sowie eine Punktlichtquelle mit der Farbe Grün, der
 * Position (-1,-1, 2) und der Dämpfung (0.1, 0.1, 0.3). Die resultierende Szene
 * sollte schließlich wie in Abbildung 3 aussehen.
 * </p>
 * 
 * Project: MMI_9<br />
 * Class: J3DFrame<br />
 * Date: 19.03.2012
 * 
 * @author xx
 */
public class J3DFrame extends JFrame
{
	private static final long serialVersionUID = 1L;
	private final Canvas3D canvas;
	private final SimpleUniverse universe;

	/**
	 * 
	 */
	public J3DFrame()
	{
		super("Java 3D");

		this.canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
		this.universe = new SimpleUniverse(this.canvas);

		final Transform3D stepBack = new Transform3D();
		stepBack.setTranslation(new Vector3d(0D, 0D, 5D));
		final Transform3D rotation = new Transform3D();
		rotation.setRotation(new AxisAngle4d(-1D, 1D, 0D, (30D * Math.PI) / 180D));

		final Transform3D viewTransform = new Transform3D();
		viewTransform.mul(rotation, stepBack);
		this.universe.getViewingPlatform().getMultiTransformGroup().getTransformGroup(0)
				.setTransform(viewTransform);

		final OrbitBehavior behavior = new OrbitBehavior(this.canvas);
		behavior.setSchedulingBounds(new BoundingSphere(new Point3d(0D, 0D, 0D), Double.MAX_VALUE));
		this.universe.getViewingPlatform().setViewPlatformBehavior(behavior);

		this.universe.addBranchGraph(createScene());

		this.getContentPane().add("Center", this.canvas);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(600, 400);
	}

	/**
	 * Scene erzeugen
	 * 
	 * @return
	 */
	private static BranchGroup createScene()
	{

		final BranchGroup branchgroup = new BranchGroup();

		/*
		 * Ändern Sie an dieser Stelle den Code für Aufgabe 9.5
		 */
		final Material sphereMaterial = new Material();
		sphereMaterial.setAmbientColor(new Color3f(Color.BLUE));
		sphereMaterial.setEmissiveColor(new Color3f(Color.BLACK));
		sphereMaterial.setDiffuseColor(new Color3f(Color.BLUE));

		final Appearance sphereAppearance = new Appearance();
		sphereAppearance.setMaterial(sphereMaterial);

		final Transform3D sphereTransform = new Transform3D();
		final TransformGroup sphereTG = new TransformGroup(sphereTransform);
		sphereTG.addChild(new Sphere(1F, Primitive.GENERATE_NORMALS, 500, sphereAppearance));
		branchgroup.addChild(sphereTG);

		final BoundingSphere BSphere = new BoundingSphere(new Point3d(0D, 0D, 0D), Double.MAX_VALUE);

		final AmbientLight aLight = new AmbientLight(true, new Color3f(Color.GRAY));
		aLight.setInfluencingBounds(BSphere);
		branchgroup.addChild(aLight);

		final DirectionalLight dLight = new DirectionalLight(true, new Color3f(Color.WHITE),
				new Vector3f(-1F, -1F, -0.1F));
		dLight.setInfluencingBounds(BSphere);
		branchgroup.addChild(dLight);

		final PointLight pLight = new PointLight(true, new Color3f(Color.GREEN), new Point3f(-1F,
				-1F, 2F), new Point3f(0.1F, 0.1F, 0.3F));
		pLight.setInfluencingBounds(BSphere);
		branchgroup.addChild(pLight);

		return branchgroup;
	}

	public static void main(final String[] args)
	{
		final J3DFrame frame = new J3DFrame();
		frame.setVisible(true);
	}
}
Weißt du, was in der Aufgabenstellung mit "Glanzlicht: Weiß mit Exponent 10.0." gemeint ist? Ich finde in der Material-Klasse keine geeignete Methode
 

truesoul

Top Contributor
Hallo.

Schonmal das versucht:


Java:
int backDistance = 1000000;
View view = simpleUniverse.getViewer().getView();

view.setFrontClipDistance(0.01);
view.setBackClipDistance(backDistance);
view.getPhysicalBody().setNominalEyeOffsetFromNominalScreen(0.0);

Was welche Methode bewirkt findest du ja in der Java3D Api ;)
Bissl mit der Distanzen spielen und schauen was passiert.

Gruß
 
W

Wishmaster51

Gast
Danke :) Das Problem ist eher, dass mir die Anweisung "Glanzlicht: Weiß mit Exponent 10.0." inhaltlich nicht klar ist, also was ist damit gemeint?
 
W

Wishmaster51

Gast
Ah, dann ist mit "Exponent" also "shininess" gemeint, danke.

Habe nun alles im Konstruktor gesetzt, und es sieht wie gewünscht aus:
Java:
		final Material sphereMaterial = new Material(new Color3f(Color.BLUE), new Color3f(
				Color.BLACK), new Color3f(Color.BLUE), new Color3f(Color.WHITE), 10F);
Danke für die Hilfe :)
 

Ähnliche Java Themen

Neue Themen


Oben