/******************************************************************************* * 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.views; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.TextPropertyDescriptor; import org.simantics.proconf.g3d.Activator; import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase; import org.simantics.proconf.g3d.base.ThreeDimensionalEditorPart; import org.simantics.proconf.g3d.scenegraph.IGeometryNode; import org.simantics.proconf.g3d.scenegraph.IGraphicsNode; import org.simantics.proconf.g3d.scenegraph.ISelectableNode; import org.simantics.utils.ui.gfx.ImageCache; import com.jme.scene.Geometry; import com.jme.scene.Node; import com.jme.scene.SceneElement; import com.jme.scene.Spatial; import com.jme.scene.batch.GeomBatch; public class ScenegraphViewPart extends ViewPart{ private static final ImageDescriptor GEOMETRY_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/geometry.png"); private static final ImageDescriptor BATCH_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/batch.png"); private static final ImageDescriptor NODE_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/node.png"); TreeViewer viewer; IPartListener listener; Action showJMEAction; @Override public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL| SWT.V_SCROLL); viewer.setContentProvider(new GNScenegraphContentProvider()); viewer.setLabelProvider(new GNScenegraphLabelProvider()); getSite().setSelectionProvider(viewer); makeActions(); IActionBars actionBar = getViewSite().getActionBars(); contributeToActionBars(actionBar); listener = new IPartListener() { @Override public void partActivated(IWorkbenchPart part) { if (part instanceof ThreeDimensionalEditorPart) { ThreeDimensionalEditorPart p = (ThreeDimensionalEditorPart)part; Object newInput = p.getEditor(); if (viewer.getInput() != newInput) viewer.setInput(newInput); } else { //viewer.setInput(null); } } @Override public void partBroughtToTop(IWorkbenchPart part) { } @Override public void partClosed(IWorkbenchPart part) { } @Override public void partDeactivated(IWorkbenchPart part) { } @Override public void partOpened(IWorkbenchPart part) { } }; for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) { w.getPartService().addPartListener(listener); } } protected void makeActions() { showJMEAction = new Action("jME",Action.AS_CHECK_BOX) { @Override public void run() { Object input = viewer.getInput(); viewer.setInput(null); if (this.isChecked()) { viewer.setContentProvider(new JMEScenegraphContentProvider()); viewer.setLabelProvider(new JMEScenegraphLabelProvider()); } else { viewer.setContentProvider(new GNScenegraphContentProvider()); viewer.setLabelProvider(new GNScenegraphLabelProvider()); } viewer.setInput(input); } }; } protected void contributeToActionBars(IActionBars bars) { fillLocalToolBar(bars.getToolBarManager()); fillLocalPullDown(bars.getMenuManager()); bars.updateActionBars(); } protected void fillLocalToolBar(IToolBarManager manager) { manager.add(showJMEAction); } protected void fillLocalPullDown(IMenuManager manager) { } @Override public void setFocus() { viewer.getControl().setFocus(); } public void dispose() { for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) { w.getPartService().removePartListener(listener); } super.dispose(); } private class JMEScenegraphContentProvider implements ITreeContentProvider { @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof JMEAdaptable) parentElement = ((JMEAdaptable)parentElement).getElement(); if (parentElement instanceof Node) { Node n = (Node)parentElement; Object o[] = new Object[n.getChildren().size()]; for (int i = 0; i < n.getChildren().size(); i++) { o[i] = new JMEAdaptable(n.getChild(i)); } return o; } if (parentElement instanceof Geometry) { Geometry g = (Geometry)parentElement; Object o[] = new Object[g.getBatchCount()]; for (int i = 0 ; i < g.getBatchCount(); i++) o[i] = new JMEAdaptable(g.getBatch(i)); return o; } return null; } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof ThreeDimensionalEditorBase) { SceneElement root = ((ThreeDimensionalEditorBase)inputElement).getRenderingComponent().getRoot(); if (root != null) return new Object[]{new JMEAdaptable(root)}; } return new Object[0]; } @Override public Object getParent(Object element) { SceneElement e; if (element instanceof JMEAdaptable) e = ((JMEAdaptable)element).getElement(); else e = (SceneElement)element; if (e instanceof Spatial) { Spatial s = (Spatial)e; return s.getParent(); } if (e instanceof GeomBatch) { GeomBatch g = (GeomBatch)e; return g.getParentGeom(); } return null; } @Override public boolean hasChildren(Object element) { if (element instanceof JMEAdaptable) element = ((JMEAdaptable)element).getElement(); if (element instanceof Node) { Node n = (Node)element; if (n.getChildren() == null) return false; return n.getChildren().size() > 0; } if (element instanceof Geometry) { Geometry g = (Geometry)element; return g.getBatchCount() > 0; } return false; } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void dispose() { } } private class JMEScenegraphLabelProvider extends LabelProvider { @Override public String getText(Object element) { if (element == null) return null; if (element instanceof JMEAdaptable) element = ((JMEAdaptable)element).getElement(); SceneElement e = (SceneElement)element; return e.getName() + " : " + e.getClass(); } @Override public Image getImage(Object element) { if (element == null) return null; if (element instanceof JMEAdaptable) element = ((JMEAdaptable)element).getElement(); ImageDescriptor desc = null; if (element instanceof GeomBatch) desc = BATCH_IMAGE; else if (element instanceof Geometry) desc = GEOMETRY_IMAGE; else if (element instanceof Node) desc = NODE_IMAGE; else return null; return ImageCache.getInstance().getImage(desc); } } private class GNScenegraphContentProvider implements ITreeContentProvider { @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof GNAdaptable) parentElement = ((GNAdaptable)parentElement).getNode(); IGraphicsNode node = (IGraphicsNode)parentElement; Object children[] = new Object[node.getChildren().size()]; Iterator it = node.getChildren().iterator(); for (int i = 0; i < node.getChildren().size(); i++) { children[i] = new GNAdaptable(it.next()); } return children; } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof ThreeDimensionalEditorBase) { IGraphicsNode root = ((ThreeDimensionalEditorBase)inputElement).getScenegraphAdapter().getRootNode(); if (root != null) return new Object[]{new GNAdaptable(root)}; } return new Object[0]; } @Override public Object getParent(Object element) { if (element instanceof GNAdaptable) element = ((GNAdaptable)element).getNode(); IGraphicsNode node = (IGraphicsNode)element; return node.getParent(); } @Override public boolean hasChildren(Object element) { if (element instanceof GNAdaptable) element = ((GNAdaptable)element).getNode(); IGraphicsNode node = (IGraphicsNode)element; return node.getChildren().size() > 0; } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void dispose() { } } private class GNScenegraphLabelProvider extends LabelProvider { @Override public String getText(Object element) { if (element instanceof GNAdaptable) element = ((GNAdaptable)element).getNode(); IGraphicsNode node = (IGraphicsNode)element; return node.getGroup().getName() + " : " + node.getClass(); } @Override public Image getImage(Object element) { ImageDescriptor desc = NODE_IMAGE; // if (element instanceof GeomBatch) // desc = BATCH_IMAGE; // else if (element instanceof Geometry) // desc = GEOMETRY_IMAGE; // else if (element instanceof Node) // desc = NODE_IMAGE; // else // return null; return ImageCache.getInstance().getImage(desc); } } private class JMEAdaptable implements IAdaptable { SceneElement element; public JMEAdaptable(SceneElement element) { assert (element != null); this.element = element; } @SuppressWarnings("unchecked") @Override public Object getAdapter(Class adapter) { if (adapter == IPropertySource.class) { return new JMEProperties(element); } return null; } public SceneElement getElement() { return element; } } private class GNAdaptable implements IAdaptable { IGraphicsNode node; public GNAdaptable(IGraphicsNode node) { assert (node != null); this.node = node; } @SuppressWarnings("unchecked") @Override public Object getAdapter(Class adapter) { if (adapter == IPropertySource.class) { return new GNProperties(node); } return null; } public IGraphicsNode getNode() { return node; } } private static final String NAME = "name"; private static final String CULL_MODE = "cullmode"; private static final String CULL_MODES[] = {"Inherit","Dynamic","Always","Never"}; private static final String LIGHT_MODE = "lightmode"; private static final String LIGHT_MODES[] = {"Off","Combine First","Combine Closest","Combine Recent Enabled","Inherit","Replace"}; private static final String LOCAL_CULL_MODE = "localcullmode"; private static final String LOCAL_LIGHT_MODE = "locallightmode"; private static final String LOCAL_NORMALS_MODE = "localnormalsmode"; private static final String LOCAL_RENDER_QUEUE_MODE ="localrenderqueuemode"; private static final String LOCAL_TEXTURE_COMBINE_MODE = "localtexturecombinemode"; private static final String LOCKS = "locks"; private static final String NORMALS_MODE = "normalsmode"; private static final String NORMALS_MODES[] = {"Inherit","Use Provided","Normalize Provided","Normalize if scaled","Off"}; private static final String RENDER_QUEUE_MODE = "renderqueuemode"; private static final String RENDER_QUEUE_MODES[] = {"Inherit","Skip","Opaque","Transparent","Ortho"}; private static final String TEXTURE_COMBINE_MODE = "texturecombinemode"; private static final String TEXTURE_COMBINE_MODES[] = {"Off","First","Closest","Recent enabled","Inherit","Replace"}; private static final String BOOLEAN_VALUES[] = {"False","True"}; private class JMEProperties implements IPropertySource { SceneElement element; public JMEProperties(SceneElement element) { this.element = element; } @Override public Object getEditableValue() { return this; } @Override public IPropertyDescriptor[] getPropertyDescriptors() { List desc = new ArrayList(); desc.add(new TextPropertyDescriptor(NAME,"Name")); desc.add(new ComboBoxPropertyDescriptor(CULL_MODE,"Cull Mode",CULL_MODES)); desc.add(new ComboBoxPropertyDescriptor(LIGHT_MODE,"Light Combine Mode",LIGHT_MODES)); desc.add(new ComboBoxPropertyDescriptor(LOCAL_CULL_MODE,"Local Cull Mode",CULL_MODES)); desc.add(new ComboBoxPropertyDescriptor(LOCAL_LIGHT_MODE,"Local Light Combine Mode",LIGHT_MODES)); desc.add(new ComboBoxPropertyDescriptor(LOCAL_NORMALS_MODE,"Local Normals Mode",NORMALS_MODES)); desc.add(new ComboBoxPropertyDescriptor(LOCAL_RENDER_QUEUE_MODE,"Local Render Queue Mode",RENDER_QUEUE_MODES)); desc.add(new ComboBoxPropertyDescriptor(LOCAL_TEXTURE_COMBINE_MODE,"Local Texture Combine Mode",TEXTURE_COMBINE_MODES)); desc.add(new TextPropertyDescriptor(LOCKS,"Locks")); desc.add(new ComboBoxPropertyDescriptor(NORMALS_MODE,"Normals Mode",NORMALS_MODES)); desc.add(new ComboBoxPropertyDescriptor(RENDER_QUEUE_MODE,"Render Queue Mode",RENDER_QUEUE_MODES)); desc.add(new ComboBoxPropertyDescriptor(TEXTURE_COMBINE_MODE,"Texture Combine Mode",TEXTURE_COMBINE_MODES)); return desc.toArray(new IPropertyDescriptor[desc.size()]); } @Override public Object getPropertyValue(Object id) { if (id == NAME) { return element.getName(); } else if (id == CULL_MODE) { return element.getCullMode(); } else if (id == LIGHT_MODE) { return element.getLightCombineMode(); } else if (id == LOCAL_CULL_MODE) { return element.getLocalCullMode(); } else if (id == LOCAL_LIGHT_MODE) { return element.getLocalLightCombineMode(); } else if (id == LOCAL_NORMALS_MODE) { return element.getLocalNormalsMode(); } else if (id == LOCAL_RENDER_QUEUE_MODE) { return element.getLocalRenderQueueMode(); } else if (id == LOCAL_TEXTURE_COMBINE_MODE) { return element.getLocalTextureCombineMode(); } else if (id == LOCKS) { return element.getLocks(); } else if (id == NORMALS_MODE) { return element.getNormalsMode(); } else if (id == RENDER_QUEUE_MODE) { return element.getRenderQueueMode(); } else if (id == TEXTURE_COMBINE_MODE) { return element.getTextureCombineMode(); } // element.getZOrder(); // element.isCollidable(); return null; } @Override public boolean isPropertySet(Object id) { return false; } @Override public void resetPropertyValue(Object id) { } @Override public void setPropertyValue(Object id, Object value) { if (id == NAME) { element.setName((String)value); } else if (id == CULL_MODE) { element.setCullMode((Integer)value); } else if (id == LIGHT_MODE) { element.setLightCombineMode((Integer)value); } else if (id == LOCAL_CULL_MODE) { } else if (id == LOCAL_LIGHT_MODE) { } else if (id == LOCAL_NORMALS_MODE) { } else if (id == LOCAL_RENDER_QUEUE_MODE) { } else if (id == LOCAL_TEXTURE_COMBINE_MODE) { } else if (id == LOCKS) { element.setLocks((Integer)value); } else if (id == NORMALS_MODE) { element.setNormalsMode((Integer)value); } else if (id == RENDER_QUEUE_MODE) { element.setRenderQueueMode((Integer)value); } else if (id == TEXTURE_COMBINE_MODE) { element.setTextureCombineMode((Integer)value); } } } private static final String SELECTED = "selected"; private static final String HIGHLIGHTED = "highlighted"; private static final String VISIBLE = "visible"; private class GNProperties implements IPropertySource { IGraphicsNode node; public GNProperties(IGraphicsNode node) { this.node = node; } @Override public Object getEditableValue() { return this; } @Override public IPropertyDescriptor[] getPropertyDescriptors() { List desc = new ArrayList(); if (node instanceof ISelectableNode) { //ISelectableNode n = (ISelectableNode)node; desc.add(new ComboBoxPropertyDescriptor(SELECTED,"Selected",BOOLEAN_VALUES)); desc.add(new ComboBoxPropertyDescriptor(HIGHLIGHTED,"Highlighted",BOOLEAN_VALUES)); desc.add(new ComboBoxPropertyDescriptor(VISIBLE,"Visible",BOOLEAN_VALUES)); } return desc.toArray(new IPropertyDescriptor[desc.size()]); } @Override public Object getPropertyValue(Object id) { if (node instanceof ISelectableNode) { ISelectableNode n = (ISelectableNode)node; if (id == SELECTED) { if (n.isSelected()) return 1; return 0; } else if (id == HIGHLIGHTED) { if (n.isHighlighted()) return 1; return 0; } else if (id == VISIBLE) { if (n.isVisible()) return 1; return 0; } } if (node instanceof IGeometryNode) { //IGeometryNode n = (IGeometryNode)node; } return null; } @Override public boolean isPropertySet(Object id) { return false; } @Override public void resetPropertyValue(Object id) { } @Override public void setPropertyValue(Object id, Object value) { if (node instanceof ISelectableNode) { ISelectableNode n = (ISelectableNode)node; boolean b = ((Integer)value) == 1; if (id == SELECTED) { n.setSelected(b); } else if (id == HIGHLIGHTED) { n.setHighlighted(b); } else if (id == VISIBLE) { n.setVisible(b); } } } } }