I want to implement more functions to the SceneComposer

First i apologize if my english is bad, because i’m Brazilian :slight_smile: . JMonkey now is my hobby, and i want to decrease the maximum of functions in runtime. Then came the idea of i want to implement more functions to the scene composer, but i don’t know if i can to have acess to the scene composer code and do it. I still not contribute with some jmp user contribuition and i don’t know who do it, then i want that anyone help me who do it. I want to do somewhat who :

  • create any type of CollisionShape to a mesh in the scene composer window instead do it in runtime.
  • set the mesh’s material’s face cull mode in the scene composer too.
  • and etc.
1 Like

You can find basic instructions on how to compile and extend jMP in the wiki. I try to extend that info as good as I can during development, but jMP still has some slightly messy parts internally… I am trying to outline the base functionality of the development environment first and then want to improve the single parts, the whole “feel” of the software should still be alpha but show what can be done so to speak :wink:



So I agree that in the end there should be way more functions in jMP. About the mesh functions, they should be pretty easy to implement as “Properties” of the mesh nodes in the SceneExplorer. This is the class that defines that nodes behaviour and its very easy to extend. As you see it uses reflection to access the parameters of the Mesh.



About the extended physics parameters, they might fit into the SceneComposer… I was also thinking about creating a separate plugin for physics editing, maybe including some test objects etc. Look at the beginnings of the TerrainEditor for the idea of multiple plugins. Atm the TerrainEditor also opens a j3o file just like the SceneComposer and then it would have buttons, lists etc. for terrain editing just like the SceneComposer. This is the first step of creating multiple plugins. In a second step, multiple plugins could open for one j3o file. So when opening the file, the SceneComposer, TerrainEditor and maybe a PhysicsEditor window open at the bottom and you can switch between them to do stuff in your scene. The most problematic part about this is the handling of the camera and the visual tools (like cursor widget etc.).



Whats big on the TODO list is this:

  • Swing widgets for editing properties like vectors, rotation etc. in the “Properties” window
  • 3D widgets for editing properties and showing selection in the “SceneViewer” window (rotation widget, light shape etc.)



    Cheers,

    Normen
1 Like

ok :), thanks for the information, i’ll to follow yours counsels and to try implement more function to the jme3 alpha 2 :slight_smile: .

I’m trying to create a module to jme plataform, then i created a class called “JmeCollisionShape” to test if it will be displayed into Scene Explorer Window.

But it isn’t displayed :frowning: . What should i do more to it to be displayed ?

This is my class :

[java]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package org.glaucomardano.mylibraly.jme.collisionshape;



    import com.jme3.bullet.collision.shapes.CollisionShape;

    import com.jme3.gde.core.scene.SceneApplication;

    import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;

    import com.jme3.math.Vector3f;

    import java.awt.Image;

    import java.io.IOException;

    import java.util.concurrent.Callable;

    import java.util.concurrent.ExecutionException;

    import org.openide.actions.DeleteAction;

    import org.openide.nodes.Children;

    import org.openide.nodes.Sheet;

    import org.openide.util.Exceptions;

    import org.openide.util.ImageUtilities;

    import org.openide.util.actions.SystemAction;



    /**

    *
  • @author Administrador

    */

    @org.openide.util.lookup.ServiceProvider(service = AbstractSceneExplorerNode.class)

    public class JmeCollisionShape extends AbstractSceneExplorerNode {



    private CollisionShape shape;

    private static Image smallImage =

    ImageUtilities.loadImage(

    “org/glaucomardamo/mylibraly/jme/collisionshape/shape.gif”);



    public JmeCollisionShape() {

    }



    public JmeCollisionShape(CollisionShape shape) {

    super(Children.LEAF);

    this.shape = shape;

    lookupContents.add(shape);

    lookupContents.add(this);

    setName(“Shape”);

    }



    @Override

    public Image getIcon(int type) {

    return smallImage;

    }



    @Override

    public Image getOpenedIcon(int type) {

    return smallImage;

    }



    @Override

    protected Sheet createSheet() {

    Sheet sheet = Sheet.createDefault();

    Sheet.Set set = Sheet.createPropertiesSet();

    set.setDisplayName(“Shape”);

    set.setName(“Shape”);

    if (shape == null) {

    return sheet;

    }

    set.put(makeProperty(shape, Vector3f.class, “getScale”, “setScale”, “scale”));

    return super.createSheet();

    }



    @Override

    protected SystemAction[] createActions() {

    return new SystemAction[]{

    SystemAction.get(DeleteAction.class)

    };

    }



    @Override

    public boolean canDestroy() {

    return true;

    }



    @Override

    public void destroy() throws IOException {

    try {

    SceneApplication.getApplication().enqueue(new Callable() {



    @Override

    public Void call() throws Exception {

    return null;

    }

    }).get();

    } catch (InterruptedException e) {

    Exceptions.printStackTrace(e);

    } catch (ExecutionException e) {

    Exceptions.printStackTrace(e);

    }

    }



    @Override

    public Class getExplorerObjectClass() {

    return CollisionShape.class;

    }



    @Override

    public Class getExplorerNodeClass() {

    return JmeCollisionShape.class;

    }

    }

    [/java]

They have to be displayed as children of some node… So only items that extend Spatial appear “automatically” because the Node displays them as their children. To display this item it would have to be added to the JmePhysicsCollisionObject children based on their CollisionShape.

1 Like

How can i add it to JmePhysicsCollisionObject :wink: ? I still don’t discovered how i can do it.

?

I would be faster writing the code than explaining it in a more detailled way than I already did… And wtf, two and a half hours and you bump your post?? High on cocaine or something??

No, I just wanna help with contributions :wink: . but without to disturb :slight_smile: .

They have to be displayed as children of some node.. So only items that extend Spatial appear “automatically” because the Node displays them as their children. To display this item it would have to be added to the JmePhysicsCollisionObject children based on their CollisionShape

Normen, i already did all things you said me. I did some tests, but my Spatial type wasn't automatically used and displayed in the SceneExplorer :( . I don't know more what to do. I'll review my concepts of "Netbeans Node API".

@org.openide.util.lookup.ServiceProvider(service = AbstractSceneExplorerNode.class)

This needs to be

@org.openide.util.lookup.ServiceProvider(service = SceneExplorerNode.class)

I already did it. But anyway thanks.

Then your type of spatial is not in the tree… This technique is used for all current Spatial types.

Then your type of spatial is not in the tree.. This technique is used for all current Spatial types.

Ok normen, now i did a test, i created a class called JmePhysicsNodeTest, very similar with "JmePhysicsNode" with you created ;) , but called "JmePhysicsNodeTest" at name and display name. see yourself:

[java]/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package org.glaucomardano.mylibraly.jme.collisionshape;

import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.gde.core.sceneexplorer.nodes.JmePhysicsCollisionObject;
import com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerChildren;
import com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode;
import com.jme3.math.Vector3f;
import java.awt.Image;
import org.openide.loaders.DataObject;
import org.openide.nodes.Sheet;
import org.openide.util.ImageUtilities;

/**
*
* @author Glauco
*/

@org.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)
public class JmePhysicsNodeTest extends JmePhysicsCollisionObject {

private static Image smallImage =
ImageUtilities.loadImage("org/glaucomardamo/mylibraly/jme/collisionshape/shape.gif");
private PhysicsNode spatial;

public JmePhysicsNodeTest() {
}

public JmePhysicsNodeTest(PhysicsNode spatial, SceneExplorerChildren children) {
super(spatial, children);
getLookupContents().add(spatial);
this.spatial = spatial;
}

@Override
public Image getIcon(int type) {
return smallImage;
}

@Override
public Image getOpenedIcon(int type) {
return smallImage;
}

@Override
protected Sheet createSheet() {
Sheet sheet = super.createSheet();
Sheet.Set set = Sheet.createPropertiesSet();
set.setDisplayName("PhysicsNodeTest");
set.setName("PhysicsNodeTest");
PhysicsNode obj = spatial;//getLookup().lookup(Spatial.class);
if (obj == null) {
return sheet;
}

set.put(makeProperty(obj, float.class, "getFriction", "setFriction", "Friction"));
set.put(makeProperty(obj, float.class, "getMass", "setMass", "Mass"));
set.put(makeProperty(obj, boolean.class, "isKinematic", "setKinematic", "Kinematic"));
set.put(makeProperty(obj, Vector3f.class, "getGravity", "setGravity", "Gravity"));
set.put(makeProperty(obj, float.class, "getLinearDamping", "setLinearDamping", "Linear Damping"));
set.put(makeProperty(obj, float.class, "getAngularDamping", "setAngularDamping", "Angular Damping"));
set.put(makeProperty(obj, float.class, "getRestitution", "setRestitution", "Restitution"));

set.put(makeProperty(obj, float.class, "getLinearSleepingThreshold", "setLinearSleepingThreshold", "Linear Sleeping Threshold"));
set.put(makeProperty(obj, float.class, "getAngularSleepingThreshold", "setAngularSleepingThreshold", "Angular Sleeping Threshold"));

sheet.put(set);
return sheet;

}

@Override
public Class getExplorerObjectClass() {
return PhysicsNode.class;
}

@Override
public Class getExplorerNodeClass() {
return JmePhysicsNodeTest.class;
}

@Override
public org.openide.nodes.Node[] createNodes(Object key, DataObject key2, boolean cookie) {
SceneExplorerChildren children=new SceneExplorerChildren((com.jme3.scene.Spatial)key);
children.setReadOnly(cookie);
children.setDataObject(key2);
return new org.openide.nodes.Node[]{new JmePhysicsNodeTest((PhysicsNode) key, children).setReadOnly(cookie)};
}
}
[/java]

Then i execute my module, and i open my scene with a PhysicsNode included (already created with the button "create/update PhysicsNode") . In the SceneExplorer Window's tree i can't see the JmePhysicsNodeTest spatial, i can see just the JmePhysicsNode spatial. See ( forget what i painted at image ) :



i didn't get it :( .
Without to forget that in the OutPut window appears it :
Warning: org.glaucomardano.mylibraly lacks a unit test dependency on org.netbeans.libs.junit4; using default dependencies for compatibility
and it :
java.io.FileNotFoundException: C:UsersGlauco.jmonkeyplatformlwjgl.dll < --- ( i ignored)
But i already did it.
Is needed to configurate the bundler.properties or the layer.xml ???
I'll study the Nodes API now :) , so i'll discover what i'm doing wrong.
Thinking better, i'll study the Essencial Netbeans Plataform complete tutorial :) .

You cannot override existing Spatial types.

Hi everyone, i’m creating a jmp module and i encountered a problem when i try to import j3o file types.

I have a action that is actived for a context menu item for j3o file types :



[java]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package org.glaucomardano.mymodule;



    import com.jme3.asset.AssetManager;

    import com.jme3.bullet.nodes.PhysicsNode;

    import com.jme3.export.binary.BinaryImporter;

    import com.jme3.gde.core.assets.ProjectAssetManager;

    import com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerChildren;

    import com.jme3.scene.Spatial;

    import java.awt.event.ActionListener;

    import java.awt.event.ActionEvent;

    import java.io.IOException;

    import org.openide.explorer.ExplorerManager;

    import org.openide.loaders.DataObject;

    import org.openide.nodes.Node;

    import com.jme3.gde.core.sceneexplorer.nodes.JmePhysicsNode;

    import java.io.ByteArrayInputStream;

    import org.netbeans.api.project.FileOwnerQuery;

    import org.netbeans.api.project.Project;

    import org.openide.filesystems.FileObject;

    import org.openide.util.Exceptions;



    //This action is a context menu item for j3o file types

    public final class EditPhysicsNodeAction implements ActionListener {



    //the model context

    private final DataObject context;



    public EditPhysicsNodeAction(DataObject context) {

    this.context = context;

    //try to find the model’s project asset manager to

    //import it as a com.jme3.scene.Node

    FileObject modelObj = context.getPrimaryFile();

    Project projObj = FileOwnerQuery.getOwner(modelObj);

    ProjectAssetManager projAssMgr = new ProjectAssetManager(

    projObj,

    projObj.getProjectDirectory().getFileObject(“assets”).getPath());

    AssetManager assetManager = projAssMgr.getManager();

    try {

    ByteArrayInputStream baos = new ByteArrayInputStream(modelObj.asBytes());

    BinaryImporter imp = new BinaryImporter();

    imp.setAssetManager(assetManager);

    com.jme3.scene.Node model = (com.jme3.scene.Node)imp.load(baos);

    } catch (IOException ex) {

    Exceptions.printStackTrace(ex);

    }

    }



    public void actionPerformed(ActionEvent ev) {

    // TODO use context

    PhysicsEditorTopComponent editor =

    PhysicsEditorTopComponent.findInstance();

    editor.open();

    editor.requestActive();

    PhysicsExplorerTopComponent explorer =

    new PhysicsExplorerTopComponent();

    explorer.open();

    explorer.requestActive();

    ExplorerManager mgr = explorer.getExplorerManager();

    Node node =

    mgr.getRootContext().getChildren().getNodeAt(0).getChildren().getNodeAt(0);

    JmePhysicsNode jmenode = (JmePhysicsNode)node;

    PhysicsNode phynode = (PhysicsNode)jmenode.getLookup().lookup(

    Spatial.class);

    mgr.setRootContext(new org.glaucomardano.mymodule.JmePhysicsNode(

    phynode, new SceneExplorerChildren(phynode)));

    }

    }

    [/java]



    This is the exception that occurs at line 47 :



    java.lang.RuntimeException: Given root path not a directory

    at com.jme3.asset.plugins.FileLocator.setRootPath(FileLocator.java:59)

    at com.jme3.asset.ImplHandler.tryLocate(ImplHandler.java:120)

    at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:226)

    at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:272)

    at com.jme3.texture.Texture.read(Texture.java:635)

    at com.jme3.texture.Texture2D.read(Texture2D.java:193)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:451)

    at com.jme3.material.MatParam.read(MatParam.java:128)

    at com.jme3.material.Material$MatParamTexture.read(Material.java:133)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readStringSavableMap(BinaryInputCapsule.java:661)

    at com.jme3.material.Material.read(Material.java:694)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:451)

    at com.jme3.scene.Geometry.read(Geometry.java:290)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:465)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:581)

    at com.jme3.scene.Node.read(Node.java:536)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:465)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:581)

    at com.jme3.scene.Node.read(Node.java:536)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:465)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:581)

    at com.jme3.scene.Node.read(Node.java:536)

    at com.jme3.bullet.collision.PhysicsCollisionObject.read(PhysicsCollisionObject.java:292)

    at com.jme3.bullet.nodes.PhysicsNode.read(PhysicsNode.java:793)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:465)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:581)

    at com.jme3.scene.Node.read(Node.java:536)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:477)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:465)

    at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:581)

    at com.jme3.scene.Node.read(Node.java:536)

    at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:288)

    at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:196)

    at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:118)

    at org.glaucomardano.mymodule.EditPhysicsNodeAction.(EditPhysicsNodeAction.java:47)

    Caused: java.lang.reflect.InvocationTargetException

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at org.openide.awt.InjectorExactlyOne.actionPerformed(InjectorExactlyOne.java:77)

    at org.openide.awt.ContextAction$Performer.actionPerformed(ContextAction.java:226)

    at org.openide.awt.ContextManager.actionPerformed(ContextManager.java:240)

    at org.openide.awt.ContextAction.actionPerformed(ContextAction.java:109)

    at org.openide.util.actions.ActionInvoker$1.run(ActionInvoker.java:93)

    at org.openide.util.actions.ActionInvoker.doPerformAction(ActionInvoker.java:116)

    at org.openide.util.actions.ActionInvoker.invokeAction(ActionInvoker.java:99)

    at org.openide.awt.GeneralAction$DelegateAction.actionPerformed(GeneralAction.java:219)

    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)

    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)

    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)

    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)

    at javax.swing.AbstractButton.doClick(AbstractButton.java:357)

    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1223)

    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1264)

    at java.awt.Component.processMouseEvent(Component.java:6263)

    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)

    at java.awt.Component.processEvent(Component.java:6028)

    at java.awt.Container.processEvent(Container.java:2041)

    at java.awt.Component.dispatchEventImpl(Component.java:4630)

    at java.awt.Container.dispatchEventImpl(Container.java:2099)

    at java.awt.Component.dispatchEvent(Component.java:4460)

    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)

    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)

    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)

    at java.awt.Container.dispatchEventImpl(Container.java:2085)

    at java.awt.Component.dispatchEvent(Component.java:4460)

    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)

    at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:137)

    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)

    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)

    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)

    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)

    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)

    [catch] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

You should never create a new ProjectAssetManager object but rather get it from the Lookup of each object:

[java]

ProjectAssetManager manager=getLookup().lookup(ProjectAssetManager.class);

[/java]

You also dont need to use ByteArrayInputStream etc… its all implemented in BinaryModelDataObject.loadAsset(), look at the existing classes.

When i try add my plugin to the repository appears the following exception :



SVN command returned with the following error:

Server sent unexpected return value (500 Internal Server Error )in response to MKACTIVITY request.



But i still didn’t the following step :

-Ask the managers or developers for access to the gc project



What need i do now?

Well, how does it look, how does it work? A physics editor you said? Any screenshots/videos?

This editor is a output window of physics editing based on TerrainEditor, but with 2 simple functions :

-add to PhysicsSpace;

-remove from PhysicsSpace.

At least it serves to do a simple physics test. But i’ll release updates over time.

I’m thinking also in add collision shape nodes to the scene explorer’s physics nodes and more other things.

I did a video that shows the simple function of this plugin.

1 Like