# Universe mit texturen und lichteffekten



## mrno (16. Dez 2005)

Hi,
ich probiere teste gerade mal java3d. Ich habe folgendes vor ich habe eine Sonne, die Erde und den Mond erstellt. Auf der Kugel der Erde wird eine texture gelegt. Nun möchte ich es haben das die lichteffekte der Sonne mit auf die texture übertragen wird. Wie mache ich das? Bis jetzt sind nur am mond die schatteneffekte erkennbar.


```
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Geometry;
import javax.media.j3d.LineArray;
import javax.media.j3d.LineStripArray;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.PositionPathInterpolator;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Text3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Text2D;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class Universe extends JFrame{
	private static final Color3f BLACK = new Color3f(0f,0f,0f);
	private static final Color3f WHITE = new Color3f(1f,1f,1f);
	private static final String TEXTURE_FNAME = "earth.jpg";
	private static final float EARTHRADIUS =0.08f;
	private static final float SUNRADIUS=0.4f;
	private static final float MOONRADIUS=0.013f;
	private static final float MOONORBIT=0.1f;
	private static final float EARTHORBIT=1.8f;
	private static final float ECLIPTIC=-0.4f;
	private static final float EARTHAXIS = 0.25f;
	private static final long MOON_EARTH=3000;
	private static final long EARTHROTATION=100;
	private static final long EARTH_SUN=36500;
	private static final int CIRCLECOORDS=32;
	
	public Universe(){
		setSize(800,600);
		setLayout(new BorderLayout());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		GraphicsConfiguration graphConfig = SimpleUniverse.getPreferredConfiguration();
		Canvas3D canvas3D = new Canvas3D(graphConfig);
		add("Center",canvas3D);
		
		SimpleUniverse simpleUni = new SimpleUniverse(canvas3D);
		
		BranchGroup sceneGraph = createSceneGraph();
		
		simpleUni.getViewingPlatform().setNominalViewingTransform();
		simpleUni.addBranchGraph(sceneGraph);
		setVisible(true);
	}
	private Point3f[]createCircleCoords(float r,int N){
		Point3f[] coords = new Point3f[N];
		int n;
		double a;
		float x,z;
		for(a=0,n=0;n<N;a=2.0*Math.PI/(N-1)*n++){
			x=(float)(r*Math.sin(a));
			z=(float)(r*Math.cos(a));
			coords[n]=new Point3f(x,0f,z);
		}
		return coords;
	}
	private Geometry createCircleGeometry(float r, int N){
		int [] stripCounts = {N};
		LineStripArray lsa = new LineStripArray(N,LineStripArray.COORDINATES,stripCounts);
		lsa.setCoordinates(0,createCircleCoords(r,N));
		return lsa;
	}
	private Geometry createLineGeometry(float l){
		LineArray la = new LineArray(2,LineArray.COORDINATES);
		la.setCoordinate(0, new Point3f(0f,-1/2f,0f));
		la.setCoordinate(1,new Point3f(0f, 1/2f,0f));
		return la;		
	}
	public BranchGroup createSceneGraph(){
		BranchGroup objRoot = new BranchGroup();
		BoundingSphere bounds = new BoundingSphere();
		
		Appearance earthAppear = new Appearance();
		earthAppear.setTexture(new TextureLoader(TEXTURE_FNAME,this).getTexture());
		Sphere earth = new Sphere (EARTHRADIUS,Primitive.GENERATE_TEXTURE_COORDS,earthAppear);
		
		Appearance sunAppear = new Appearance();
		sunAppear.setMaterial(new Material(BLACK,WHITE,WHITE,WHITE,1f));
		Sphere sun = new Sphere(SUNRADIUS,sunAppear);
		
		Appearance moonAppear = new Appearance();
		moonAppear.setMaterial(new Material(BLACK,BLACK,WHITE,WHITE,1f));
		Sphere moon = new Sphere(MOONRADIUS,moonAppear);
		
		Shape3D earthOrbit = new Shape3D(createCircleGeometry(EARTHORBIT,CIRCLECOORDS));
		Shape3D moonOrbit = new Shape3D(createCircleGeometry(MOONORBIT,CIRCLECOORDS));
		Shape3D earthAxis= new Shape3D(createLineGeometry(EARTHAXIS));
		
		PointLight sunlight = new PointLight();
		sunlight.setInfluencingBounds(bounds);
		
		Transform3D moonTranslate = new Transform3D();
		moonTranslate.set(new Vector3f(0f,0f,MOONORBIT));
		TransformGroup objMoonTranslate = new TransformGroup(moonTranslate);
		
		TransformGroup objMoon = new TransformGroup();
		objMoon.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		RotationInterpolator rotIntMonth= new RotationInterpolator(new Alpha(-1,MOON_EARTH),objMoon);
		rotIntMonth.setSchedulingBounds(bounds);
		
		TransformGroup objEarth = new TransformGroup();
		objEarth.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		RotationInterpolator rotIntDay = new RotationInterpolator(new Alpha(-1,EARTHROTATION),objEarth);
		rotIntDay.setSchedulingBounds(bounds);
		
		Transform3D ecliptic = new Transform3D();
		ecliptic.rotZ(ECLIPTIC);
		TransformGroup objEcliptic = new TransformGroup(ecliptic);
		
		float[]knots = new float[CIRCLECOORDS];
		for(int n = 0 ; n< CIRCLECOORDS;++n){
			knots[n]=(float)n*(1/(float)(CIRCLECOORDS-1));
		}
		
		TransformGroup objYear = new TransformGroup();
		objYear.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		PositionPathInterpolator rotIntYear = new PositionPathInterpolator(new Alpha(-1,EARTH_SUN),objYear,new Transform3D(),knots,createCircleCoords(EARTHORBIT,CIRCLECOORDS));
		rotIntYear.setSchedulingBounds(bounds);
		
		TransformGroup objRotate = new TransformGroup();
		objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		MouseRotate mouseRotate = new MouseRotate();
		mouseRotate.setTransformGroup(objRotate);
		mouseRotate.setSchedulingBounds(bounds);
		
		objRoot.addChild(objRotate);
		objRotate.addChild(mouseRotate);
		objRotate.addChild(sun);
		objRotate.addChild(sunlight);
		objRotate.addChild(objYear);
		objRotate.addChild(earthOrbit);
		
		objYear.addChild(rotIntYear);
		objYear.addChild(objEcliptic);
		objYear.addChild(objMoon);
		
		objEcliptic.addChild(objEarth);
		
		objEarth.addChild(rotIntDay);
		objEarth.addChild(earth);
		objEarth.addChild(earthAxis);
		
		objMoon.addChild(rotIntMonth);
		objMoon.addChild(objMoonTranslate);
		objMoon.addChild(moonOrbit);
		
		objMoonTranslate.addChild(moon);
		
		objRoot.compile();
		return objRoot;
	}
	public static void main(String[]args){
		new Universe();
	}
}
```

Hoffe mir kann jemand helfen


----------



## DeepBlue (19. Dez 2005)

Hio

Ich bin mir nicht sicher, ob es das ist, was du meinst. Aber damit die Erde von Licht beeinflusst werden kann, musst du ihr, glaube ich, neben der Textur auch ein Material zuweisen.

mfg DeeP


----------



## mrno (19. Dez 2005)

Hat leider nicht funktioniert. Es ist immer noch das skin ohne lichteffekte zu sehen.


----------



## Illuvatar (19. Dez 2005)

Ah ja da fällt mir auf  was du vergessen hast ist, die Normals zu generieren. Das ist auch ein primitive-flag, also mahcst du das zum Beispiel mit

```
Sphere earth = new Sphere (EARTHRADIUS,Primitive.GENERATE_TEXTURE_COORDS | Primitive.GENERATE_NORMALS,earthAppear);
```


----------



## Guest (19. Dez 2005)

Jetzt sieht es schonmal besser aus. Danke für den tip. nun habe ich nur das problem das die Seite die der sonne abgeneigt ist normal aussieht und die andere seite weiß ist. Wie schaffe ich es jetzt das die abgewannte seite sehr dunkel , fast schwarz ist und die andere seite im nomalen farbton?


----------



## Illuvatar (19. Dez 2005)

Da wirst du mit den Werten im Material rumspielen müssen.


----------



## DeepBlue (20. Dez 2005)

Jo, das liegt am Material. Kannst du vielleicht mal posten, wie die Codezeile für das Material ist ?


----------



## mrno (20. Dez 2005)

Hier ist die Zeile:

```
earthAppear.setMaterial(new Material(BLACK,WHITE,WHITE,WHITE,1f));
```
An der stelle an der das BLACK sein sollte, hat die texture den Original farbton.


----------



## DeepBlue (3. Jan 2006)

Hast du mal mit dem letzten Wert (also 1f) ein wenig experimentiert ?


----------



## mrno (3. Jan 2006)

hab ich schon gemacht. Ich bekomme die textur nicht dunkler als das originale. Er hellt es nur auf an manchen stellen


----------



## DeepBlue (4. Jan 2006)

Es ist zwar keine schöne Lösung, aber wie wärs, wenn du die Textur einfach dunkler machst ? Wenn sie dann an der richtigen Stelle wieder aufgehellt wird, sollte das doch den gewünschten Effekt erzielen, oder ?


----------

