# [Java3D] Rotieren der Scene NICHT des POV



## mattn (5. Aug 2010)

ich habe folgendes problem...

habe eine scene, welche in der primitive objekte hinzugefügt wurden...
dann habe ich der scene verschiedene lichter hinzugefügt....

um alles zu betrachten habe ich das OrbitBehavior oder das PickRotateBehavior benutzt.

nur leider musst ich feststellen, das ich nicht die scene an sich, sondern nur meinen blickpunkt ändere.
da die lichter nur von einer seite kommen, seh ich wenn ich die scene einmal per hand rotieren lasse auch die schattenseite.... das will ich aber vermeiden, da ich nur den "schönen" effekt von vorn sehen will.

also die frage ist, wie kann ich einstellen das nur die objekte(alle) rotierieren und nicht das licht...
falls ihr mich nicht versteht, folgendes beispiel
______________________

ZIEL
ich sitz im dunkeln, habe nur eine tischlampe
in der hand habe ich ein objekt(z.b. einen würfel) nun dreh ich den würfel --> das licht bleibt an ein und der selben stelle --> ich sehe nur die beleuchtete seite, mit einem gewissen schattierungseffekt...

AKTUELLER STAND
ich sitz im dunkeln, habe nur eine tischlampe
ich stell den würfel auf den tisch(in den lichtkegel) und lauf um den tisch herum --> ich sehe zwar alle seiten, aber eben auch die hintere schattenseite

hier das KSKB
(erst herauszoomen-damit man die rotation sieht) - beim betrachten 


```
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;

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.GraphicsConfigTemplate3D;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.SpotLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.picking.PickRotateBehavior;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;


public class foo extends Applet {
	static Canvas3D c;
	
	public void init(){
		System.out.println("init");
		setLayout(new BorderLayout());
//		GraphicsConfigTemplate3D 
		
		c = new Canvas3D(
	            GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(
	            new GraphicsConfigTemplate3D()));
		
		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
//		Canvas3D c= new Canvas3D(config);
		add("Center", c);
		SimpleUniverse u = new SimpleUniverse(c);	
		// verschiebe ViewingPlatform:
		TransformGroup vpTG = null;
		Transform3D vpT3D = new Transform3D();
		vpTG = u.getViewingPlatform().getViewPlatformTransform();
		vpT3D.set(new Vector3f(0.0f, 0.0f, 10.0f));
		vpTG.setTransform(vpT3D);
		//Behavior zum Betrachten der Szene
		OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
		orbit.setSchedulingBounds(new BoundingSphere());
		u.getViewingPlatform().setViewPlatformBehavior(orbit);
		u.addBranchGraph(createSceneGraph());
	}
	
	private BranchGroup createSceneGraph() {
		// TODO Auto-generated method stub
		BranchGroup rootBG = new BranchGroup();
			
		
		TransformGroup boxTG = new TransformGroup();
		boxTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		boxTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

		
		
		Transform3D boxT3D = new Transform3D();
		Appearance app = new Appearance();
		
		PointLight pl = new PointLight(	new Color3f(1f,0f,0f), 
										new Point3f(-2f,0f,0f), 
										new Point3f(0f,0.25f,0f));
		SpotLight sl = new SpotLight(	new Color3f(0f,1f,0f), 
										new Point3f(5.75f,-1f,-8.9f), 
										new Point3f(0f,0f,0f), 
										new Vector3f(-1f,0f,0f), 
										(float)Math.toRadians(25), 
										7f );
		AmbientLight al = new AmbientLight(new Color3f(0.3f,0.3f,0.5f));
		BoundingSphere BigBounds = new BoundingSphere(new Point3d(),100000);
		pl.setInfluencingBounds(BigBounds);
		sl.setInfluencingBounds(BigBounds);
		al.setInfluencingBounds(BigBounds);
		
		rootBG.addChild(pl);
		rootBG.addChild(sl);
		rootBG.addChild(al);
				
		boxT3D.setTranslation(new Vector3f(0f,0f,8f));
		boxT3D.setRotation(new AxisAngle4f(1f,1f,1f,(float)Math.toRadians(-60)));
		boxTG.setTransform(boxT3D);
		
		app.setMaterial(new Material(	new Color3f(0.8f,0.0f,0.0f),
										new Color3f(0.0f,0.0f,0.0f),
										new Color3f(0.8f,0.0f,0.0f),
										new Color3f(1.0f,0.0f,0.0f), 
										10f));
		
		boxTG.addChild(new Box(0.1f,0.1f,0.1f,Sphere.GENERATE_NORMALS,app));
				
        
        rootBG.addChild(boxTG);
		//PickRotateBehavior pickR = new PickRotateBehavior(rootBG, c, BigBounds); 
		//rootBG.addChild(pickR);

		
		
		rootBG.compile();
		return rootBG;
	}
}
```

rotieren - linke maustaste
verschieben - rechte maustaste 
zoom -mausrad


----------



## truesoul (6. Aug 2010)

Hallo mattn, 

also wenn du OrbitBehavior und PickBehaviors gleichzeitig verwendest , solltest du erstmal entscheiden welchen von beiden du grad benutzen willst.
Also möchtest du durch die Scene "fliegen" deaktivierst du PickBehavior oder andersrum. ( setEnable( ... ) )
Weil PickBehavior nur das gepickte Objekt Objekt bewegt wird es schwierig alle(??) Objekte gleichzeitig zu bewegen. Also:

1.
Entweder du benutzt einen dritten Behavior ( MouseBehavior ) deaktivierst dementsprechend die anderen beiden wenn du grad den benutzen willst. 
2.Oder hängst dein licht ein OrbitBehavior dran , "fliegst" dann durch die Scene mit ein Licht an der Schnauze 

P.S Nr.2 Müsste gehen habs aber nicht ausprobiert 
Mfg

EDIT:

Übrigens kannst du mit Transform3D.lookAt( .... ) dein OrbitBehavior auf deine gewünschte Position einstellen.
Dann braucht der jenige nicht heraus zoomen


----------



## mattn (6. Aug 2010)

so früh schon wach  
mir ist gester abend eine idee gekommen... hab sie gerade ausprobiert....ist noch bisschen komisch mit dem licht aber so müsst es eig gehen, oder? also struktur sieht so aus...

rootBG
|
  -->Lichter
  |
  -->TransformGroup(mit rot-zoom-Behav)
|
        -->subRootBG
|
            -->Objekte​ps
ach und truesoul... ich werd mal die 2. variante versuchen....bin mir nur schnell kleber für die lichter holen die ich mir an die "schnauze"  pappen soll 


hätt da mal noch ne frage...(hab mich erst halbwegs mit j3d "angefreundet") 
wenn ich bis über einen bestimmten pkt hinaus bzw hinein zoom verschwinden die objekte....
das kann ich doch bestimmt irgendwie ändern, das es nicht passiert....vllt iwo die bounds vergrößern?


----------



## truesoul (6. Aug 2010)

Würde es so machen:

```
rootBG // SimpleUniverse
|
--> BranchGroup 
    |
    --> TransformGroup
        |
         --> Lichter
|
--> TransformGroup 
    |
     --> Behaviors
|
 --> BranchGroup
     |
     --> Objekte
```
Im Übrigen zu Nr.2 nochmals.
Nach jeder Kamera bewegung kann man mit 

```
simpleUniverse.getViewingPlatform().getViewPlatformTransform().getTransform(Transform3D)
```
die Position der View herausfinden.
Das Transform3D wendest du dann auf das Licht an.

P.S Sekundenkleber würde ich dir nicht empfehlen zum Testen 

Übrigens habe ich zum anderen Thread auch ne Antowrt gepostet


----------



## truesoul (6. Aug 2010)

Ja mit :


```
View v = simpleUniverse.getViewer().getView();

// Einstellung für die Größe des SimpleUniverse
v.setFrontClipDistance(0.01);
v.setBackClipDistance(backDistance); // größer ist besser ;) backDistance = 1000000;z.B
v.getPhysicalBody().setNominalEyeOffsetFromNominalScreen(0.0);
```


----------

