/******************************************************************************* * Copyright (c) 2007- VTT Technical Research Centre of Finland. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.proconf.g3d.gizmo; import javax.vecmath.AxisAngle4f; import javax.vecmath.Color4f; import javax.vecmath.Quat4f; import javax.vecmath.Tuple3d; import javax.vecmath.Tuple3f; import javax.vecmath.Vector3d; import javax.vecmath.Vector3f; import org.simantics.proconf.g3d.Activator; import org.simantics.proconf.g3d.base.JmeRenderingComponent; import org.simantics.proconf.g3d.base.VecmathJmeTools; import org.simantics.proconf.g3d.preferences.PreferenceConstants; import com.jme.renderer.Renderer; import com.jme.scene.Node; public abstract class AbstractGizmo implements Gizmo{ private Node position; private Node rotate; private Node scale; private boolean changed = false; private double userScale = 1.0; public AbstractGizmo() { createGroups(); } public void setChanged(boolean b) { changed = b; } public boolean isChanged() { return changed; } public double getUserScale() { return Activator.getDefault().getPreferenceStore().getDouble(PreferenceConstants.GIZMO_SCALE); } public void setScale(float scale) { this.scale.setLocalScale(scale); } public void setScale(Vector3f scale) { this.scale.setLocalScale(VecmathJmeTools.get(scale)); } public Vector3d getPosition() { return VecmathJmeTools.getD(position.getWorldTranslation()); } public Vector3f getPositionFloat() { return VecmathJmeTools.get(position.getWorldTranslation()); } public void setPosition(Tuple3d position) { this.position.setLocalTranslation(VecmathJmeTools.get(position)); } public void setPosition(Vector3f position) { this.position.setLocalTranslation(VecmathJmeTools.get(position)); } public void setRotation(Quat4f q) { rotate.setLocalRotation(VecmathJmeTools.get(q)); } public void setRotation(AxisAngle4f q) { rotate.setLocalRotation(VecmathJmeTools.get(q)); } public Node getNode() { userScale = getUserScale(); return position; } protected Node getGizmoNode() { return scale; } private void createGroups() { position = new Node(); rotate = new Node(); scale = new Node(); position.attachChild(rotate); rotate.attachChild(scale); position.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT); } public void update(Tuple3d position, Tuple3d cameraPosition, JmeRenderingComponent component) { setPosition(position); com.jme.math.Vector3f p = VecmathJmeTools.get(position); p.subtractLocal(VecmathJmeTools.get(cameraPosition)); rotate.getLocalRotation().inverse().multLocal(p); if (component.getProjectionPolicy() == JmeRenderingComponent.PERSPECTIVE_PROJECTION) { double distance = p.length(); // (bug caused in Xith->JME translation ?) p.negateLocal(); double fov = component.getFieldOfView(); float s = (float) (Math.sin(fov) * distance * 0.1); // scaling factor was 0.2 with Xith s *= (float)userScale; Vector3f scale = new Vector3f(1.f, 1.f, 1.f); if (p.x > 0.f) scale.x = -1.f; if (p.y > 0.f) scale.y = -1.f; if (p.z > 0.f) scale.z = -1.f; scale.scale(s); setScale(scale); } else { Vector3f scale = new Vector3f(1.f, 1.f, 1.f); float s = component.getScreenScale() / 5.f; s *= (float)userScale; if (p.x > 0.f) scale.x = -1.f; if (p.y > 0.f) scale.y = -1.f; if (p.z > 0.f) scale.z = -1.f; scale.scale(s); setScale(scale); } } public void update(Tuple3d cameraPosition, JmeRenderingComponent component) { com.jme.math.Vector3f p = VecmathJmeTools.get(getPosition()); p.subtractLocal(VecmathJmeTools.get(cameraPosition)); rotate.getLocalRotation().inverse().multLocal(p); if (component.getProjectionPolicy() == JmeRenderingComponent.PERSPECTIVE_PROJECTION) { double distance = p.length(); double fov = component.getFieldOfView(); float s = (float)(Math.sin(fov) * distance * 0.1); // scaling factor was 0.2 with Xith s *= (float)userScale; Vector3f scale = new Vector3f(1.f,1.f,1.f); if (p.x > 0.f) scale.x = -1.f; if (p.y > 0.f) scale.y = -1.f; if (p.z > 0.f) scale.z = -1.f; scale.scale(s); setScale(scale); } else { Vector3f scale = new Vector3f(1.f,1.f,1.f); float s = component.getScreenScale()/5.f; s *= (float)userScale; if (p.x > 0.f) scale.x = -1.f; if (p.y > 0.f) scale.y = -1.f; if (p.z > 0.f) scale.z = -1.f; scale.scale(s); setScale(scale); } } protected void setCoordinate(float array[], int index, Tuple3f c) { index *= 3; array[index++] = c.x; array[index++] = c.y; array[index] = c.z; } protected void setColor(float array[], int index, Color4f c) { index *= 4; array[index++] = c.x; array[index++] = c.y; array[index++] = c.z; array[index] = c.w; } }