> From: Jure Zabkar <[EMAIL PROTECTED]>
>
> Is it possible to set the view so that it would automatically compute
> the bounds of the object and put it in the center of the screen? I have
> different objects, different sizes and placements, so I sometimes don't
> see an object until I move it so that it can be seen.
If you have the "usual" scene graph structure which puts the object in one
BranchGraph and the view in another BranchGraph you can inquire the bounds of
the object and modify the view to show the object. An example of this is the
SimpleVrml97Viewer. I've attached the source this class below.
The basic idea is to add the object to the scene, inquire the bounds of the
object and then modify the view to show the object. Set the view by translating
the view so that it is located at the center of the bounds and then translating
the view "back" far enough to display the entire diameter of the bounds.
Another way to do this (used by Vrml97Viewer) is use a constant view and modify
a transform above the object to translate and scale the object to fit in the
view. The source for Vrml97Viewer (along with alot of other good J3D/VRML
content) can be found at http://www.vrml.org/WorkingGroups/vrml-java3d.
Hope this helps
Doug Gehringer
Sun Microsystems
/*
* @(#)SimpleVrml97Viewer.java 1.6 98/09/18 14:58:38
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*
* @Author: Doug Gehringer
* @Author: Rick Goldberg
*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.net.URL;
import java.net.MalformedURLException;
import com.sun.j3d.loaders.vrml97.VrmlLoader;
import com.sun.j3d.loaders.Scene;
public class SimpleVrml97Viewer extends Applet implements ActionListener {
String location;
Canvas3D canvas;
SimpleUniverse universe;
TransformGroup vpTransGroup;
VrmlLoader loader;
View view;
Panel panel;
Label label;
BranchGroup sceneRoot;
TransformGroup examineGroup;
BranchGroup sceneGroup;
BoundingSphere sceneBounds;
DirectionalLight headLight;
AmbientLight ambLight;
TextField textField;
Cursor waitCursor;
Cursor handCursor;
SimpleVrml97Viewer(String initLocation) {
setLayout(new BorderLayout());
canvas = new Canvas3D(null);
add("Center",canvas);
panel = new Panel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
textField = new TextField(initLocation,60);
textField.addActionListener(this);
label = new Label("Location:");
panel.add(label);
panel.add(textField);
add("North",panel);
waitCursor = new Cursor(Cursor.WAIT_CURSOR);
handCursor = new Cursor(Cursor.HAND_CURSOR);
universe = new SimpleUniverse(canvas);
ViewingPlatform viewingPlatform = universe.getViewingPlatform();
vpTransGroup = viewingPlatform.getViewPlatformTransform();
Viewer viewer = universe.getViewer();
view = viewer.getView();
setupBehavior();
loader = new VrmlLoader();
gotoLocation(initLocation);
}
public void actionPerformed(ActionEvent ae) {
gotoLocation(textField.getText());
}
void gotoLocation(String location) {
canvas.setCursor(waitCursor);
if (sceneGroup != null) {
sceneGroup.detach();
}
Scene scene = null;
try {
URL loadUrl = new URL(location);
try {
// load the scene
scene = loader.load(new URL(location));
} catch (Exception e) {
System.out.println("Exception loading URL:" + e);
}
} catch (MalformedURLException badUrl) {
// location may be a path name
try {
// load the scene
scene = loader.load(location);
} catch (Exception e) {
System.out.println("Exception loading file from path:" + e);
}
}
if (scene != null) {
// get the scene group
sceneGroup = scene.getSceneGroup();
sceneGroup.setCapability(BranchGroup.ALLOW_DETACH);
sceneGroup.setCapability(BranchGroup.ALLOW_BOUNDS_READ);
// add the scene group to the scene
examineGroup.addChild(sceneGroup);
// now that the scene group is "live" we can inquire the bounds
sceneBounds = (BoundingSphere)sceneGroup.getBounds();
// set up a viewpoint to include the bounds
setViewpoint();
}
canvas.setCursor(handCursor);
}
void setViewpoint() {
Transform3D viewTrans = new Transform3D();
Transform3D eyeTrans = new Transform3D();
// point the view at the center of the object
Point3d center = new Point3d();
sceneBounds.getCenter(center);
double radius = sceneBounds.getRadius();
Vector3d temp = new Vector3d(center);
viewTrans.set(temp);
// pull the eye back far enough to see the whole object
double eyeDist = 1.4*radius / Math.tan(view.getFieldOfView() / 2.0);
temp.x = 0.0;
temp.y = 0.0;
temp.z = eyeDist;
eyeTrans.set(temp);
viewTrans.mul(eyeTrans);
// set the view transform
vpTransGroup.setTransform(viewTrans);
}
private void setupBehavior() {
sceneRoot = new BranchGroup();
examineGroup = new TransformGroup();
examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
examineGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
examineGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
sceneRoot.addChild(examineGroup);
BoundingSphere behaviorBounds = new BoundingSphere(new Point3d(),
Double.MAX_VALUE);
MouseRotate mr = new MouseRotate();
mr.setTransformGroup(examineGroup);
mr.setSchedulingBounds(behaviorBounds);
sceneRoot.addChild(mr);
MouseTranslate mt = new MouseTranslate();
mt.setTransformGroup(examineGroup);
mt.setSchedulingBounds(behaviorBounds);
sceneRoot.addChild(mt);
MouseZoom mz = new MouseZoom();
mz.setTransformGroup(examineGroup);
mz.setSchedulingBounds(behaviorBounds);
sceneRoot.addChild(mz);
BoundingSphere lightBounds =
new BoundingSphere(new Point3d(), Double.MAX_VALUE);
ambLight = new AmbientLight(true, new Color3f(1.0f, 1.0f, 1.0f));
ambLight.setInfluencingBounds(lightBounds);
ambLight.setCapability(Light.ALLOW_STATE_WRITE);
sceneRoot.addChild(ambLight);
headLight = new DirectionalLight();
headLight.setCapability(Light.ALLOW_STATE_WRITE);
headLight.setInfluencingBounds(lightBounds);
sceneRoot.addChild(headLight);
universe.addBranchGraph(sceneRoot);
}
public static void main(String[] args) {
String locString = null;
if (args.length == 0) {
locString = System.getProperties().getProperty("user.dir") +
"/parts/simple.wrl";
} else {
if (args.length != 1) {
System.out.println("Usage: SimpleVrml97Viewer [pathname|URL]");
System.exit(0);
} else {
locString = args[0];
}
}
new MainFrame(new SimpleVrml97Viewer(locString), 780, 780);
}
}