|
|
|
@ -5,15 +5,35 @@ |
|
|
|
|
package com.jme3.gde.scenecomposer; |
|
|
|
|
|
|
|
|
|
import com.jme3.asset.AssetManager; |
|
|
|
|
import com.jme3.bounding.BoundingVolume; |
|
|
|
|
import com.jme3.collision.Collidable; |
|
|
|
|
import com.jme3.collision.CollisionResults; |
|
|
|
|
import com.jme3.collision.UnsupportedCollisionException; |
|
|
|
|
import com.jme3.gde.core.scene.SceneApplication; |
|
|
|
|
import com.jme3.gde.core.scene.controller.SceneToolController; |
|
|
|
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; |
|
|
|
|
import com.jme3.light.Light; |
|
|
|
|
import com.jme3.light.LightList; |
|
|
|
|
import com.jme3.light.PointLight; |
|
|
|
|
import com.jme3.light.SpotLight; |
|
|
|
|
import com.jme3.material.Material; |
|
|
|
|
import com.jme3.material.RenderState.BlendMode; |
|
|
|
|
import com.jme3.math.Vector2f; |
|
|
|
|
import com.jme3.math.Vector3f; |
|
|
|
|
import com.jme3.renderer.Camera; |
|
|
|
|
import com.jme3.renderer.RenderManager; |
|
|
|
|
import com.jme3.renderer.ViewPort; |
|
|
|
|
import com.jme3.renderer.queue.RenderQueue.Bucket; |
|
|
|
|
import com.jme3.scene.Geometry; |
|
|
|
|
import com.jme3.scene.Node; |
|
|
|
|
import com.jme3.scene.SceneGraphVisitor; |
|
|
|
|
import com.jme3.scene.Spatial; |
|
|
|
|
import com.jme3.scene.control.AbstractControl; |
|
|
|
|
import com.jme3.scene.control.BillboardControl; |
|
|
|
|
import com.jme3.scene.control.Control; |
|
|
|
|
import com.jme3.scene.shape.Quad; |
|
|
|
|
import com.jme3.texture.Texture; |
|
|
|
|
import java.util.Queue; |
|
|
|
|
import java.util.concurrent.Callable; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -28,10 +48,14 @@ public class SceneComposerToolController extends SceneToolController { |
|
|
|
|
private ComposerCameraController cameraController; |
|
|
|
|
private ViewPort overlayView; |
|
|
|
|
private Node onTopToolsNode; |
|
|
|
|
private Node lightMarkersNode; |
|
|
|
|
private Material lightMarkerMaterial; |
|
|
|
|
|
|
|
|
|
public SceneComposerToolController(Node toolsNode, AssetManager manager, JmeNode rootNode) { |
|
|
|
|
super(toolsNode, manager); |
|
|
|
|
this.rootNode = rootNode; |
|
|
|
|
lightMarkersNode = new Node("lightMarkersNode"); |
|
|
|
|
toolsNode.attachChild(lightMarkersNode); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public SceneComposerToolController(AssetManager manager) { |
|
|
|
@ -179,4 +203,144 @@ public class SceneComposerToolController extends SceneToolController { |
|
|
|
|
editTool.draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Node getLightMarkersNode() { |
|
|
|
|
return lightMarkersNode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Adds a marker for the light to the scene if it does not exist yet |
|
|
|
|
*/ |
|
|
|
|
public void addLightMarker(Light light) { |
|
|
|
|
if (!(light instanceof PointLight) && !(light instanceof SpotLight)) |
|
|
|
|
return; // only handle point and spot lights
|
|
|
|
|
|
|
|
|
|
Spatial s = lightMarkersNode.getChild(light.getName()); |
|
|
|
|
if (s != null) { |
|
|
|
|
// update location maybe? Remove old and replace with new?
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LightMarker lm = new LightMarker(light); |
|
|
|
|
lightMarkersNode.attachChild(lm); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Removes a light marker from the scene's tool node |
|
|
|
|
*/ |
|
|
|
|
public void removeLightMarker(Light light) { |
|
|
|
|
Spatial s = lightMarkersNode.getChild(light.getName()); |
|
|
|
|
s.removeFromParent(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private Material getLightMarkerMaterial() { |
|
|
|
|
if (lightMarkerMaterial == null) { |
|
|
|
|
Material mat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
|
|
|
|
Texture tex = manager.loadTexture("com/jme3/gde/scenecomposer/lightbulb32.png"); |
|
|
|
|
mat.setTexture("ColorMap", tex); |
|
|
|
|
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); |
|
|
|
|
lightMarkerMaterial = mat; |
|
|
|
|
} |
|
|
|
|
return lightMarkerMaterial; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected void refreshNonSpatialMarkers() { |
|
|
|
|
lightMarkersNode.detachAllChildren(); |
|
|
|
|
addMarkers(rootNode.getLookup().lookup(Node.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void addMarkers(Node parent) { |
|
|
|
|
|
|
|
|
|
for (Light light : parent.getLocalLightList()) |
|
|
|
|
addLightMarker(light); |
|
|
|
|
|
|
|
|
|
for (Spatial s : parent.getChildren()) { |
|
|
|
|
if (s instanceof Node) |
|
|
|
|
addMarkers((Node)s); |
|
|
|
|
else { |
|
|
|
|
//TODO later if we include other types of non-spatial markers
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A marker on the screen that shows where a point light or |
|
|
|
|
* a spot light is. This marker is not part of the scene, |
|
|
|
|
* but is part of the tools node. |
|
|
|
|
*/ |
|
|
|
|
protected class LightMarker extends Geometry { |
|
|
|
|
private Light light; |
|
|
|
|
|
|
|
|
|
protected LightMarker() {} |
|
|
|
|
|
|
|
|
|
protected LightMarker(Light light) { |
|
|
|
|
this.light = light; |
|
|
|
|
Quad q = new Quad(0.5f, 0.5f); |
|
|
|
|
this.setMesh(q); |
|
|
|
|
this.setMaterial(getLightMarkerMaterial()); |
|
|
|
|
this.addControl(new LightMarkerControl()); |
|
|
|
|
this.setQueueBucket(Bucket.Transparent); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected Light getLight() { |
|
|
|
|
return light; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void setLocalTranslation(Vector3f location) { |
|
|
|
|
super.setLocalTranslation(location); |
|
|
|
|
if (light instanceof PointLight) |
|
|
|
|
((PointLight)light).setPosition(location); |
|
|
|
|
else if (light instanceof SpotLight) |
|
|
|
|
((SpotLight)light).setPosition(location); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void setLocalTranslation(float x, float y, float z) { |
|
|
|
|
super.setLocalTranslation(x, y, z); |
|
|
|
|
if (light instanceof PointLight) |
|
|
|
|
((PointLight)light).setPosition(new Vector3f(x,y,z)); |
|
|
|
|
else if (light instanceof SpotLight) |
|
|
|
|
((SpotLight)light).setPosition(new Vector3f(x,y,z)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Updates the marker's position whenever the light has moved. |
|
|
|
|
* It is also a BillboardControl, so this marker always faces |
|
|
|
|
* the camera |
|
|
|
|
*/ |
|
|
|
|
protected class LightMarkerControl extends BillboardControl { |
|
|
|
|
|
|
|
|
|
LightMarkerControl(){ |
|
|
|
|
super(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
protected void controlUpdate(float f) { |
|
|
|
|
super.controlUpdate(f); |
|
|
|
|
LightMarker marker = (LightMarker) getSpatial(); |
|
|
|
|
if (marker != null) { |
|
|
|
|
if (marker.getLight() instanceof PointLight) { |
|
|
|
|
marker.setLocalTranslation(((PointLight)marker.getLight()).getPosition()); |
|
|
|
|
} else if (marker.getLight() instanceof SpotLight) { |
|
|
|
|
marker.setLocalTranslation(((SpotLight)marker.getLight()).getPosition()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
protected void controlRender(RenderManager rm, ViewPort vp) { |
|
|
|
|
super.controlRender(rm, vp); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Control cloneForSpatial(Spatial sptl) { |
|
|
|
|
LightMarkerControl c = new LightMarkerControl(); |
|
|
|
|
c.setSpatial(sptl); |
|
|
|
|
//TODO this isn't correct, none of BillboardControl is copied over
|
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|