Files
secondo/Javagui/viewer/spatial3D/LightBranchGroup.java

515 lines
15 KiB
Java
Raw Normal View History

2026-01-23 17:03:45 +08:00
//This file is part of SECONDO.
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation; either version 2 of the License, or
//(at your option) any later version.
//SECONDO is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//You should have received a copy of the GNU General Public License
//along with SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package viewer.spatial3D;
import tools.Reporter;
import java.awt.Color;
import java.awt.Component;
import java.awt.AWTEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Group;
import javax.media.j3d.Light;
import javax.media.j3d.PointLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOnBehaviorPost;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;
import com.sun.j3d.utils.behaviors.mouse.MouseBehaviorCallback;
import java.util.Enumeration;
/**
* A class for lighting for Spatial3dViewer
* with brightness regulator
*
*/
public class LightBranchGroup extends BranchGroup {
public static final int MAX_LEVEL = 6; // range 0-5
/**
* a private internal class of mouse behavior modified from
*
* MouseTranslation.java, MouseZoom.java, MouseWheelZoom.java of Sun Microsystems
*
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
* USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
private class LightMouseBehavior extends MouseBehavior {
private LightPanel panel;
private double x_factor = 1.0;
private double y_factor = 1.0;
private double z_factor = 1.0;
private MouseBehaviorCallback callback = null;
public LightMouseBehavior(TransformGroup transformGroup, LightPanel _panel) {
super(transformGroup);
panel = _panel;
}
public LightMouseBehavior(){
super(0);
panel = null;
}
/*
public LightMouseBehavior(int flags) {
super(flags);
}
public LightMouseBehavior(Component c) {
super(c, 0);
}
public LightMouseBehavior(Component c, TransformGroup transformGroup) {
super(c, transformGroup);
}
public LightMouseBehavior(Component c, int flags) {
super(c, flags);
}
*/
@Override
public void initialize() {
super.initialize();
if ((flags & INVERT_INPUT) == INVERT_INPUT) {
x_factor *= -1;
y_factor *= -1;
z_factor *= -1;
invert = true;
}
}
@Override
public void processStimulus (Enumeration criteria) {
WakeupCriterion wakeup;
AWTEvent[] events;
MouseEvent evt;
while (criteria.hasMoreElements()) {
wakeup = (WakeupCriterion) criteria.nextElement();
if (wakeup instanceof WakeupOnAWTEvent) {
events = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
if (events.length > 0) {
evt = (MouseEvent) events[events.length-1];
doProcess(evt);
}
}
else if (wakeup instanceof WakeupOnBehaviorPost) {
while (true) {
synchronized (mouseq) {
if (mouseq.isEmpty()) break;
evt = (MouseEvent)mouseq.remove(0);
while ((evt.getID() == MouseEvent.MOUSE_DRAGGED) && !mouseq.isEmpty() && (((MouseEvent)mouseq.get(0)).getID() == MouseEvent.MOUSE_DRAGGED)) {
evt = (MouseEvent)mouseq.remove(0);
}
}
doProcess(evt);
}
}
}
wakeupOn(mouseCriterion);
}
void doProcess(MouseEvent evt) {
int id;
int dx, dy;
int units = 0;
Vector3d translation = new Vector3d();
processMouseEvent(evt);
if (((buttonPress) && ((flags & MANUAL_WAKEUP) == 0)) || ((wakeUp)&&((flags & MANUAL_WAKEUP) != 0))){
id = evt.getID();
// x and y direction
if (evt.isControlDown() && (id == MouseEvent.MOUSE_DRAGGED) && !evt.isAltDown() && !evt.isMetaDown()) {
x = evt.getX();
y = evt.getY();
dx = x - x_last;
dy = y - y_last;
if ((!reset)/* && ((Math.abs(dy) < 50) && (Math.abs(dx) < 50))*/) {
// Reporter.writeInfo("Mousetranslate dx: " + dx + " dy: " + dy);
transformGroup.getTransform(currXform);
translation.x = dx * x_factor*panel.getXChangeFactor();
translation.y = -dy * y_factor*panel.getYChangeFactor();
transformX.set(translation);
if (invert) {
currXform.mul(currXform, transformX);
} else {
currXform.mul(transformX, currXform);
}
transformGroup.setTransform(currXform);
transformChanged( currXform );
if (callback!=null) callback.transformChanged( MouseBehaviorCallback.TRANSLATE, currXform );
Vector3d trans = new Vector3d();
currXform.get(trans);
if(panel != null){
panel.setX(trans.x);
panel.setY(trans.y);
}
}else {
reset = false;
}
x_last = x;
y_last = y;
}
// z direction
else if (evt.isControlDown() && (id == MouseEvent.MOUSE_DRAGGED) && !evt.isMetaDown() && evt.isAltDown()){
x = evt.getX();
y = evt.getY();
dx = x - x_last;
dy = y - y_last;
if (!reset){
// Reporter.writeInfo("Mousezoom dx: " + dx + " dy: " + dy);
transformGroup.getTransform(currXform);
translation.z = dy*z_factor*panel.getZChangeFactor();
transformX.set(translation);
if (invert) {
currXform.mul(currXform, transformX);
} else {
currXform.mul(transformX, currXform);
}
transformGroup.setTransform(currXform);
transformChanged( currXform );
if (callback!=null)callback.transformChanged( MouseBehaviorCallback.ZOOM,currXform );
Vector3d trans = new Vector3d();
currXform.get(trans);
if(panel !=null)panel.setZ(trans.z);
}else {
reset = false;
}
x_last = x;
y_last = y;
// mouse wheel movement -> z direction
}else if (evt.isControlDown() && (id == MouseEvent.MOUSE_WHEEL) && !evt.isMetaDown() && evt.isControlDown()) {
MouseWheelEvent wheelEvent = (MouseWheelEvent)evt;
if (wheelEvent.getScrollType() == wheelEvent.WHEEL_UNIT_SCROLL ) {
units = wheelEvent.getUnitsToScroll();
}
if (!reset) {
// Reporter.writeInfo("MousewheelZoom");
transformGroup.getTransform(currXform);
translation.z = units*z_factor*panel.getZChangeFactor();
transformX.set(translation);
if (invert) {
currXform.mul(currXform, transformX);
} else {
currXform.mul(transformX, currXform);
}
transformGroup.setTransform(currXform);
transformChanged( currXform );
if (callback!=null) callback.transformChanged( MouseBehaviorCallback.ZOOM,currXform );
Vector3d trans = new Vector3d();
currXform.get(trans);
if(panel !=null)panel.setZ(trans.z);
}else {
reset = false;
}
}else if (evt.isControlDown() && id == MouseEvent.MOUSE_PRESSED) {
// Reporter.writeInfo("Mouse pressed");
x_last = evt.getX();
y_last = evt.getY();
}
}
}
public void transformChanged( Transform3D transform ) {
}
public void setupCallback( MouseBehaviorCallback callback ) {
this.callback = callback;
}
}
private BoundingSphere area;
private Color3f color;
private TransformGroup tg;
private LightMouseBehavior behavior;
private int brightness = 0;
// constructor
public LightBranchGroup(LightPanel panel){
super();
color = new Color3f(1.0f, 1.0f, 1.0f);
area = new BoundingSphere(new Point3d(0.0,0.0,0.0),panel.STARTING_RADIUS);
tg = new TransformGroup();
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
// create all lightis here
for(int i=0; i<MAX_LEVEL ; i++){
PointLight light = new PointLight();
light.setCapability(Light.ALLOW_INFLUENCING_BOUNDS_READ);
light.setCapability(Light.ALLOW_INFLUENCING_BOUNDS_WRITE);
light.setCapability(Light.ALLOW_COLOR_READ);
light.setCapability(Light.ALLOW_COLOR_WRITE);
light.setCapability(Light.ALLOW_STATE_READ);
light.setCapability(Light.ALLOW_STATE_WRITE);
light.setInfluencingBounds(area);
light.setEnable(false);
tg.addChild(light);
}
setBrightness(MAX_LEVEL/2);
// add behavior
behavior = new LightMouseBehavior(tg, panel);
behavior.setSchedulingBounds(area);
behavior.setEnable(false);
this.addChild(behavior);
this.addChild(tg);
setCapability(Group.ALLOW_CHILDREN_READ);
setCapability(Group.ALLOW_CHILDREN_WRITE);
setCapability(BranchGroup.ALLOW_DETACH);
compile();
}
/**
* increase brightness
*/
public void increase(){
if(brightness<MAX_LEVEL-1){
((PointLight)tg.getChild(brightness)).setEnable(true);
brightness++;
}
}
/**
* decrease brightness
*/
public void decrease(){
if(brightness>0){
((PointLight)tg.getChild(brightness)).setEnable(false);
brightness--;
}
}
/**
* getter brightness
* @return brighness in int
*/
public int getBrightness(){
return brightness;
}
/**
* setter brightness
* @param brighness in int
*/
public void setBrightness(int _brightness){
if(_brightness > MAX_LEVEL-1|| _brightness < 0) return;
for(int i = 0; i < _brightness ; i++){
((PointLight)tg.getChild(i)).setEnable(true);
}
for(int i = _brightness; i < MAX_LEVEL ; i++){
((PointLight)tg.getChild(i)).setEnable(false);
}
brightness = _brightness;
}
/**
* set wheather the position can be changable
* @param enable as boolean
*/
public void setRemovable(boolean enable){
behavior.setEnable(enable);
}
/**
* set Light area
* @param radius as double
*/
public void setArea(double _radius){
area.setRadius(_radius);
behavior.setSchedulingBounds(area);
for(int i = 0; i < MAX_LEVEL; i++){
((PointLight)tg.getChild(i)).setInfluencingBounds(area);
}
}
/**
*
* @return radius of light reachable area in double
*/
public double getArea(){
return area.getRadius();
}
/**
* switch on/off function
* @param on
*/
public void setEnable(boolean on){
for(int i=0; i<=brightness; i++){
((PointLight)tg.getChild(i)).setEnable(on);
}
}
/**
* check if the light is on
* @return return true if at least one of the PointLight is enabled, else false
*/
public boolean getEnable(){
for(int i=0; i<MAX_LEVEL ; i++){
if (((PointLight)tg.getChild(i)).getEnable()) return true;
}
return false;
}
/**
* @return color of the light
*/
public Color getColor(){
return color.get();
}
/**
* @param color to be set
*/
public void setColor(Color c){
Color3f newColor = new Color3f(c);
color = newColor;
for(int i=0; i<MAX_LEVEL; i++){
((PointLight)tg.getChild(i)).setColor(color);
}
}
/**
* @return current position in Point3d
*/
public Point3d getPosition(){
Vector3d dif = new Vector3d();
Transform3D trans = new Transform3D();
tg.getTransform(trans);
trans.get(dif);
Point3d ret = new Point3d((float)(dif.x),(float)(dif.y),(float)(dif.z));
return ret;
}
/**
* @param to be set position in Point3d
*/
public void setPosition(Point3d newPos){
Point3d currentPos = getPosition();
Point3d dif = new Point3d();
dif.sub(newPos,currentPos);
/* Reporter.writeInfo("Current Position: x: " + currentPos.x + " y: " + currentPos.y + " z: " + currentPos.z);
Reporter.writeInfo("new Position: x: " + newPos.x + " y: " + newPos.y + " z: " + newPos.z);
Reporter.writeInfo("difference: x: " + dif.x + " y: " + dif.y + " z: " + dif.z);
*/
Transform3D trans = new Transform3D();
tg.getTransform(trans);
trans.set(new Vector3d(newPos));
tg.setTransform(trans);
}
public void setX(double value){
Point3d pos = getPosition();
pos.x = value;
setPosition(pos);
}
public void setY(double value){
Point3d pos = getPosition();
pos.y = value;
setPosition(pos);
}
public void setZ(double value){
Point3d pos = getPosition();
pos.z = value;
setPosition(pos);
}
public void setMouseMoveEnable(boolean enable){
behavior.setEnable(enable);
}
public boolean getMouseMoveEnable(){
return behavior.getEnable();
}
}