Search in sources :

Example 11 with Node

use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.

the class GeometryBatchFactory method alignBuffers.

/**
     * Will ensure that all the geometries' meshes of the n sub graph have the 
     * same types of buffers
     * @param n the node to gather geometries from
     * @param option the align options 
     * @see AlignOption
     * 
     * Very experimental for now.
     */
public static void alignBuffers(Node n, AlignOption option) {
    List<Geometry> geoms = new ArrayList<Geometry>();
    gatherGeoms(n, geoms);
    //gather buffer types
    Map<VertexBuffer.Type, VertexBuffer> types = new EnumMap<VertexBuffer.Type, VertexBuffer>(VertexBuffer.Type.class);
    Map<VertexBuffer.Type, Integer> typesCount = new EnumMap<VertexBuffer.Type, Integer>(VertexBuffer.Type.class);
    for (Geometry geom : geoms) {
        for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
            if (types.get(buffer.getBufferType()) == null) {
                types.put(buffer.getBufferType(), buffer);
                logger.log(Level.FINE, buffer.getBufferType().toString());
            }
            Integer count = typesCount.get(buffer.getBufferType());
            if (count == null) {
                count = 0;
            }
            count++;
            typesCount.put(buffer.getBufferType(), count);
        }
    }
    switch(option) {
        case RemoveUnalignedBuffers:
            for (Geometry geom : geoms) {
                for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
                    Integer count = typesCount.get(buffer.getBufferType());
                    if (count != null && count < geoms.size()) {
                        geom.getMesh().clearBuffer(buffer.getBufferType());
                        logger.log(Level.FINE, "removing {0} from {1}", new Object[] { buffer.getBufferType(), geom.getName() });
                    }
                }
            }
            break;
        case CreateMissingBuffers:
            for (Geometry geom : geoms) {
                for (VertexBuffer.Type type : types.keySet()) {
                    if (geom.getMesh().getBuffer(type) == null) {
                        VertexBuffer vb = new VertexBuffer(type);
                        Buffer b;
                        switch(type) {
                            case Index:
                            case BoneIndex:
                            case HWBoneIndex:
                                b = BufferUtils.createIntBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
                                break;
                            case InterleavedData:
                                b = BufferUtils.createByteBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
                                break;
                            default:
                                b = BufferUtils.createFloatBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
                        }
                        vb.setupData(types.get(type).getUsage(), types.get(type).getNumComponents(), types.get(type).getFormat(), b);
                        geom.getMesh().setBuffer(vb);
                        logger.log(Level.FINE, "geom {0} misses buffer {1}. Creating", new Object[] { geom.getName(), type });
                    }
                }
            }
            break;
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) Type(com.jme3.scene.VertexBuffer.Type) Type(com.jme3.scene.VertexBuffer.Type)

Example 12 with Node

use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.

the class TextureAtlas method createAtlas.

/**
     * Create a texture atlas for the given root node, containing DiffuseMap, NormalMap and SpecularMap.
     * @param root The rootNode to create the atlas for.
     * @param atlasSize The size of the atlas (width and height).
     * @return Null if the atlas cannot be created because not all textures fit.
     */
public static TextureAtlas createAtlas(Spatial root, int atlasSize) {
    List<Geometry> geometries = new ArrayList<Geometry>();
    GeometryBatchFactory.gatherGeoms(root, geometries);
    TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize);
    for (Geometry geometry : geometries) {
        if (!atlas.addGeometry(geometry)) {
            logger.log(Level.WARNING, "Texture atlas size too small, cannot add all textures");
            return null;
        }
    }
    return atlas;
}
Also used : Geometry(com.jme3.scene.Geometry) ArrayList(java.util.ArrayList)

Example 13 with Node

use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.

the class LightSortTest method testSceneGraphSort.

@Test
public void testSceneGraphSort() {
    Node n = new Node("node");
    Geometry g = new Geometry("geom", new Mesh());
    SpotLight spot = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_X);
    PointLight point = new PointLight(Vector3f.UNIT_X);
    DirectionalLight directional = new DirectionalLight(Vector3f.UNIT_X);
    AmbientLight ambient = new AmbientLight();
    // Some lights are on the node
    n.addLight(spot);
    n.addLight(point);
    // .. and some on the geometry.
    g.addLight(directional);
    g.addLight(ambient);
    n.attachChild(g);
    n.updateGeometricState();
    LightList list = g.getWorldLightList();
    // check the sorting (when geom is at 0,0,0)
    assert list.get(0) instanceof AmbientLight;
    assert list.get(1) instanceof DirectionalLight;
    assert list.get(2) instanceof SpotLight;
    assert list.get(3) instanceof PointLight;
    // move the geometry closer to the point light
    g.setLocalTranslation(Vector3f.UNIT_X);
    n.updateGeometricState();
    assert list.get(0) instanceof AmbientLight;
    assert list.get(1) instanceof DirectionalLight;
    assert list.get(2) instanceof PointLight;
    assert list.get(3) instanceof SpotLight;
// now move the point light away from the geometry
// and the spot light closer
// XXX: doesn't work! jME can't detect that the light moved!
//        point.setPosition(Vector3f.ZERO);
//        spot.setPosition(Vector3f.UNIT_X);
//        n.updateGeometricState();
//        
//        assert list.get(0) instanceof AmbientLight;
//        assert list.get(1) instanceof DirectionalLight;
//        assert list.get(2) instanceof SpotLight;
//        assert list.get(3) instanceof PointLight;
}
Also used : Geometry(com.jme3.scene.Geometry) Node(com.jme3.scene.Node) Mesh(com.jme3.scene.Mesh) Test(org.junit.Test)

Example 14 with Node

use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.

the class FbxBindPose method fromElement.

@Override
public void fromElement(FbxElement element) {
    super.fromElement(element);
    for (FbxElement child : element.children) {
        if (!child.id.equals("PoseNode")) {
            continue;
        }
        FbxId node = null;
        float[] matData = null;
        for (FbxElement e : child.children) {
            if (e.id.equals("Node")) {
                node = FbxId.create(e.properties.get(0));
            } else if (e.id.equals("Matrix")) {
                double[] matDataDoubles = (double[]) e.properties.get(0);
                if (matDataDoubles.length != 16) {
                    // corrupt
                    throw new UnsupportedOperationException("Bind pose matrix " + "must have 16 doubles, but it has " + matDataDoubles.length + ". Data is corrupt");
                }
                matData = new float[16];
                for (int i = 0; i < matDataDoubles.length; i++) {
                    matData[i] = (float) matDataDoubles[i];
                }
            }
        }
        if (node != null && matData != null) {
            Matrix4f matrix = new Matrix4f(matData);
            bindPose.put(node, matrix);
        }
    }
}
Also used : FbxElement(com.jme3.scene.plugins.fbx.file.FbxElement) Matrix4f(com.jme3.math.Matrix4f) FbxId(com.jme3.scene.plugins.fbx.file.FbxId)

Example 15 with Node

use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.

the class FbxLoader method constructAnimations.

private void constructAnimations() {
    // In FBX, animation are not attached to any root.
    // They are implicitly global.
    // So, we need to use hueristics to find which node(s) 
    // an animation is associated with, so we can create the AnimControl
    // in the appropriate location in the scene.
    Map<FbxToJmeTrack, FbxToJmeTrack> pairs = new HashMap<FbxToJmeTrack, FbxToJmeTrack>();
    for (FbxAnimStack stack : animStacks) {
        for (FbxAnimLayer layer : stack.getLayers()) {
            for (FbxAnimCurveNode curveNode : layer.getAnimationCurveNodes()) {
                for (Map.Entry<FbxNode, String> nodePropertyEntry : curveNode.getInfluencedNodeProperties().entrySet()) {
                    FbxToJmeTrack lookupPair = new FbxToJmeTrack();
                    lookupPair.animStack = stack;
                    lookupPair.animLayer = layer;
                    lookupPair.node = nodePropertyEntry.getKey();
                    // Find if this pair is already stored
                    FbxToJmeTrack storedPair = pairs.get(lookupPair);
                    if (storedPair == null) {
                        // If not, store it.
                        storedPair = lookupPair;
                        pairs.put(storedPair, storedPair);
                    }
                    String property = nodePropertyEntry.getValue();
                    storedPair.animCurves.put(property, curveNode);
                }
            }
        }
    }
    // At this point we can construct the animation for all pairs ...
    for (FbxToJmeTrack pair : pairs.values()) {
        String animName = pair.animStack.getName();
        float duration = pair.animStack.getDuration();
        System.out.println("ANIMATION: " + animName + ", duration = " + duration);
        System.out.println("NODE: " + pair.node.getName());
        duration = pair.getDuration();
        if (pair.node instanceof FbxLimbNode) {
            // Find the spatial that has the skeleton for this limb.
            FbxLimbNode limbNode = (FbxLimbNode) pair.node;
            Bone bone = limbNode.getJmeBone();
            Spatial jmeSpatial = limbNode.getSkeletonHolder().getJmeObject();
            Skeleton skeleton = limbNode.getSkeletonHolder().getJmeSkeleton();
            // Get the animation control (create if missing).
            AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
            if (animControl.getSkeleton() != skeleton) {
                throw new UnsupportedOperationException();
            }
            // Get the animation (create if missing).
            Animation anim = animControl.getAnim(animName);
            if (anim == null) {
                anim = new Animation(animName, duration);
                animControl.addAnim(anim);
            }
            // Find the bone index from the spatial's skeleton.
            int boneIndex = skeleton.getBoneIndex(bone);
            // Generate the bone track.
            BoneTrack bt = pair.toJmeBoneTrack(boneIndex, bone.getBindInverseTransform());
            // Add the bone track to the animation.
            anim.addTrack(bt);
        } else {
            // Create the spatial animation
            Animation anim = new Animation(animName, duration);
            anim.setTracks(new Track[] { pair.toJmeSpatialTrack() });
            // Get the animation control (create if missing).
            Spatial jmeSpatial = pair.node.getJmeObject();
            AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
            if (animControl == null) {
                animControl = new AnimControl(null);
                jmeSpatial.addControl(animControl);
            }
            // Add the spatial animation
            animControl.addAnim(anim);
        }
    }
}
Also used : BoneTrack(com.jme3.animation.BoneTrack) HashMap(java.util.HashMap) FbxAnimCurveNode(com.jme3.scene.plugins.fbx.anim.FbxAnimCurveNode) AnimControl(com.jme3.animation.AnimControl) FbxNode(com.jme3.scene.plugins.fbx.node.FbxNode) Spatial(com.jme3.scene.Spatial) Animation(com.jme3.animation.Animation) FbxToJmeTrack(com.jme3.scene.plugins.fbx.anim.FbxToJmeTrack) Skeleton(com.jme3.animation.Skeleton) Bone(com.jme3.animation.Bone) FbxLimbNode(com.jme3.scene.plugins.fbx.anim.FbxLimbNode) FbxAnimLayer(com.jme3.scene.plugins.fbx.anim.FbxAnimLayer) HashMap(java.util.HashMap) Map(java.util.Map) FbxAnimStack(com.jme3.scene.plugins.fbx.anim.FbxAnimStack)

Aggregations

Node (com.jme3.scene.Node)135 Vector3f (com.jme3.math.Vector3f)81 Geometry (com.jme3.scene.Geometry)64 Spatial (com.jme3.scene.Spatial)53 Material (com.jme3.material.Material)51 DirectionalLight (com.jme3.light.DirectionalLight)35 Quaternion (com.jme3.math.Quaternion)32 RigidBodyControl (com.jme3.bullet.control.RigidBodyControl)26 Box (com.jme3.scene.shape.Box)24 Sphere (com.jme3.scene.shape.Sphere)19 AmbientLight (com.jme3.light.AmbientLight)17 BulletAppState (com.jme3.bullet.BulletAppState)16 ColorRGBA (com.jme3.math.ColorRGBA)15 AnimControl (com.jme3.animation.AnimControl)14 KeyTrigger (com.jme3.input.controls.KeyTrigger)14 FilterPostProcessor (com.jme3.post.FilterPostProcessor)14 HashMap (java.util.HashMap)14 CameraNode (com.jme3.scene.CameraNode)13 ArrayList (java.util.ArrayList)13 ActionListener (com.jme3.input.controls.ActionListener)12