Next: 6.10 TickTockCollision
Up: 6 Java3Dのプログラミング
Previous: 6.8 Background
Mouseで環境を軸あるいは点を中心に
回転することができる例である.
/java/jdk1.4/demo/java3d/Billboard> wc *.java
236 849 8665 Bboard.java
250 921 9386 BboardPt.java
180 662 5440 MouseRotateY.java
666 2432 23491 total
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;
public class Bboard extends Applet {
private String fontName = "TestFont";
private String textString = "Billboard";
float sl = textString.length();
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D textMat = new Transform3D();
textMat.setScale(1.2/sl);
objScale.setTransform(textMat);
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(
TransformGroup.ALLOW_TRANSFORM_WRITE);
objTrans.setCapability(
TransformGroup.ALLOW_TRANSFORM_READ);
objRoot.addChild(objTrans);
BoundingSphere bounds =
new BoundingSphere(
new Point3d(0.0,0.0,0.0), 100.0);
Appearance apText = new Appearance();
Material m = new Material();
m.setLightingEnable(true);
apText.setMaterial(m);
Appearance apEarth= new Appearance();
Material mm = new Material();
mm.setLightingEnable(true);
apEarth.setMaterial(mm);
Appearance apStone = new Appearance();
apStone.setMaterial(mm);
Font3D f3d = new Font3D(
new Font(fontName, Font.PLAIN, 2),
new FontExtrusion());
Text3D txt = new Text3D(
f3d, textString,
new Point3f( -sl/2.0f, 3.0f, 0.0f));
Shape3D textShape = new Shape3D();
textShape.setGeometry(txt);
textShape.setAppearance(apText);
TransformGroup bbTransY =
new TransformGroup();
bbTransY.setCapability(
TransformGroup.ALLOW_TRANSFORM_WRITE);
bbTransY.setCapability(
TransformGroup.ALLOW_TRANSFORM_READ);
Billboard bboardY = new Billboard( bbTransY );
objTrans.addChild( bboardY );
bboardY.setSchedulingBounds( bounds );
bboardY.setAlignmentAxis( 0.0f, 1.0f, 0.0f);
objScale.addChild( bbTransY );
bbTransY.addChild( textShape );
Transform3D cubeMat = new Transform3D();
TransformGroup cubeTrans =
new TransformGroup(cubeMat);
cubeMat.set(new Vector3d(0.9, 0.0, -1.0));
cubeTrans.setTransform(cubeMat);
cubeTrans.addChild(new ColorCube(0.3));
objTrans.addChild(cubeTrans);
TextureLoader stoneTex =
new TextureLoader(
new String("../images/stone.jpg"),
new String("RGB"), this);
if (stoneTex != null)
apStone.setTexture(stoneTex.getTexture());
TextureAttributes texAttr =
new TextureAttributes();
texAttr.setTextureMode(
TextureAttributes.MODULATE);
apStone.setTextureAttributes(texAttr);
Transform3D coneMat = new Transform3D();
TransformGroup coneTrans =
new TransformGroup(coneMat);
coneMat.set(new Vector3d(0.0, 0.0, 0.0));
coneTrans.setTransform(coneMat);
coneTrans.addChild(
new Cone(.2f, 0.8f,
Cone.GENERATE_NORMALS |
Cone.GENERATE_TEXTURE_COORDS,
apStone));
objTrans.addChild(coneTrans);
TextureLoader earthTex =
new TextureLoader(
new String("../images/earth.jpg"),
new String("RGB"), this);
if (earthTex != null)
apEarth.setTexture(earthTex.getTexture());
apEarth.setTextureAttributes(texAttr);
Transform3D cylinderMat = new Transform3D();
TransformGroup cylinderTrans =
new TransformGroup(cylinderMat);
cylinderMat.set(new Vector3d(-0.9, 0.5, -1.0));
cylinderTrans.setTransform(cylinderMat);
cylinderTrans.addChild(
new Cylinder(.35f, 2.0f,
Cylinder.GENERATE_NORMALS |
Cylinder.GENERATE_TEXTURE_COORDS,
apEarth));
objTrans.addChild(cylinderTrans);
objTrans.addChild(objScale);
Color3f bgColor =
new Color3f(0.05f, 0.05f, 0.5f);
Background bgNode = new Background(bgColor);
bgNode.setApplicationBounds(bounds);
objRoot.addChild(bgNode);
Color3f ambientColor =
new Color3f(0.1f, 0.1f, 0.1f);
AmbientLight ambientLightNode =
new AmbientLight(ambientColor);
ambientLightNode.setInfluencingBounds(bounds);
objRoot.addChild(ambientLightNode);
Color3f light1Color =
new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction =
new Vector3f(4.0f, -7.0f, -12.0f);
Color3f light2Color =
new Color3f(0.3f, 0.3f, 0.4f);
Vector3f light2Direction =
new Vector3f(-6.0f, -2.0f, -1.0f);
DirectionalLight light1
= new DirectionalLight(light1Color,
light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
DirectionalLight light2
= new DirectionalLight(light2Color,
light2Direction);
light2.setInfluencingBounds(bounds);
objRoot.addChild(light2);
apText.setMaterial(mm);
MouseRotateY behavior =
new MouseRotateY();
behavior.setTransformGroup(objTrans);
objTrans.addChild(behavior);
behavior.setSchedulingBounds(bounds);
MouseZoom behavior2 = new MouseZoom();
behavior2.setTransformGroup(objTrans);
objTrans.addChild(behavior2);
behavior2.setSchedulingBounds(bounds);
MouseTranslate behavior3 =
new MouseTranslate();
behavior3.setTransformGroup(objTrans);
objTrans.addChild(behavior3);
behavior3.setSchedulingBounds(bounds);
objRoot.compile();
return objRoot;
}
public Bboard() {
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Bboard(), 400, 400);
}
}
MouseRotateYクラスは以下のようになっている.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;
public class MouseRotateY
extends MouseBehavior {
double y_angle;
double y_factor;
public MouseRotateY(TransformGroup
transformGroup) {
super(transformGroup);
}
public MouseRotateY() {
super(0);
}
public MouseRotateY(int flags) {
super(flags);
}
public void initialize() {
super.initialize();
y_angle = 0;
y_factor = .03;
if ((flags & INVERT_INPUT) ==
INVERT_INPUT) {
invert = true;
y_factor *= -1;
}
}
public double getYFactor() {
return y_factor;
}
public void setFactor( double factor) {
y_factor = factor;
}
public void
processStimulus(Enumeration criteria) {
WakeupCriterion wakeup;
AWTEvent[] event;
int id;
int dx;
while (criteria.hasMoreElements()) {
wakeup =
(WakeupCriterion) criteria.nextElement();
if (wakeup instanceof WakeupOnAWTEvent) {
event =
((WakeupOnAWTEvent)wakeup).getAWTEvent();
for (int i=0; i<event.length; i++) {
processMouseEvent((MouseEvent) event[i]);
if (((buttonPress)&&
((flags & MANUAL_WAKEUP) == 0)) ||
((wakeUp)&&
((flags & MANUAL_WAKEUP) != 0))){
id = event[i].getID();
if ((id == MouseEvent.MOUSE_DRAGGED) &&
!((MouseEvent)event[i]).isMetaDown() &&
!((MouseEvent)event[i]).isAltDown()){
x = ((MouseEvent)event[i]).getX();
dx = x - x_last;
if (!reset){
y_angle = dx * y_factor;
transformY.rotY(y_angle);
transformGroup.getTransform(currXform);
Matrix4d mat = new Matrix4d();
currXform.get(mat);
currXform.setTranslation(
new Vector3d(0.0,0.0,0.0));
if (invert) {
currXform.mul(currXform, transformX);
currXform.mul(currXform, transformY);
} else {
currXform.mul(transformX, currXform);
currXform.mul(transformY, currXform);
}
Vector3d translation = new
Vector3d(mat.m03, mat.m13, mat.m23);
currXform.setTranslation(translation);
transformGroup.setTransform(currXform);
}
else {
reset = false;
}
x_last = x;
}
else if (id ==
MouseEvent.MOUSE_PRESSED) {
x_last =
((MouseEvent)event[i]).getX();
}
}
}
}
}
wakeupOn (mouseCriterion);
}
}
generated through LaTeX2HTML. M.Inaba 平成18年5月7日