Search in sources :

Example 6 with Spatial

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

the class TextureAtlas method makeAtlasBatch.

/**
     * Creates one geometry out of the given root spatial and merges all single
     * textures into one texture of the given size.
     * @param spat The root spatial of the scene to batch
     * @param mgr An assetmanager that can be used to create the material.
     * @param atlasSize A size for the atlas texture, it has to be large enough to hold all single textures.
     * @return A new geometry that uses the generated texture atlas and merges all meshes of the root spatial, null if the atlas cannot be created because not all textures fit.
     */
public static Geometry makeAtlasBatch(Spatial spat, AssetManager mgr, int atlasSize) {
    List<Geometry> geometries = new ArrayList<Geometry>();
    GeometryBatchFactory.gatherGeoms(spat, geometries);
    TextureAtlas atlas = createAtlas(spat, atlasSize);
    if (atlas == null) {
        return null;
    }
    Geometry geom = new Geometry();
    Mesh mesh = new Mesh();
    GeometryBatchFactory.mergeGeometries(geometries, mesh);
    applyAtlasCoords(geometries, mesh, atlas);
    mesh.updateCounts();
    mesh.updateBound();
    geom.setMesh(mesh);
    Material mat = new Material(mgr, "Common/MatDefs/Light/Lighting.j3md");
    Texture diffuseMap = atlas.getAtlasTexture("DiffuseMap");
    Texture normalMap = atlas.getAtlasTexture("NormalMap");
    Texture specularMap = atlas.getAtlasTexture("SpecularMap");
    if (diffuseMap != null) {
        mat.setTexture("DiffuseMap", diffuseMap);
    }
    if (normalMap != null) {
        mat.setTexture("NormalMap", normalMap);
    }
    if (specularMap != null) {
        mat.setTexture("SpecularMap", specularMap);
    }
    mat.setFloat("Shininess", 16.0f);
    geom.setMaterial(mat);
    return geom;
}
Also used : Geometry(com.jme3.scene.Geometry) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) Material(com.jme3.material.Material) MatParamTexture(com.jme3.material.MatParamTexture) Texture(com.jme3.texture.Texture)

Example 7 with Spatial

use of com.jme3.scene.Spatial 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 8 with Spatial

use of com.jme3.scene.Spatial 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)

Example 9 with Spatial

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

the class ObjectHelper method isParent.

/**
     * Checks if the first given OMA points to a parent of the second one.
     * The parent need not to be the direct one. This method should be called when we are sure
     * that both of the features are alred loaded because it does not check it.
     * The OMA's should point to a spatials, otherwise the function will throw ClassCastException.
     * @param supposedParentOMA
     *            the OMA of the node that we suppose might be a parent of the second one
     * @param spatialOMA
     *            the OMA of the scene's node
     * @return <b>true</b> if the first given OMA points to a parent of the second one and <b>false</b> otherwise
     */
public boolean isParent(Long supposedParentOMA, Long spatialOMA) {
    Spatial supposedParent = (Spatial) blenderContext.getLoadedFeature(supposedParentOMA, LoadedDataType.FEATURE);
    Spatial spatial = (Spatial) blenderContext.getLoadedFeature(spatialOMA, LoadedDataType.FEATURE);
    Spatial parent = spatial.getParent();
    while (parent != null) {
        if (parent.equals(supposedParent)) {
            return true;
        }
        parent = parent.getParent();
    }
    return false;
}
Also used : Spatial(com.jme3.scene.Spatial)

Example 10 with Spatial

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

the class CombinedTexture method generateSkyTexture.

/**
     * Generates a texture that will be used by the sky spatial.
     * The result texture has 6 layers. Every image in each layer has equal size and its shape is a square.
     * The size of each image is the maximum size (width or height) of the textures given.
     * The default sky generated texture size is used (this value is set in the BlenderKey) if no picture textures
     * are present or their sizes is lower than the generated texture size.
     * The textures of lower sizes are properly scaled.
     * All the textures are mixed into one and put as layers in the result texture.
     * 
     * @param horizontalColor
     *            the horizon color
     * @param zenithColor
     *            the zenith color
     * @param blenderContext
     *            the blender context
     * @return texture for the sky
     */
public TextureCubeMap generateSkyTexture(ColorRGBA horizontalColor, ColorRGBA zenithColor, BlenderContext blenderContext) {
    LOGGER.log(Level.FINE, "Preparing sky texture from {0} applied textures.", textureDatas.size());
    LOGGER.fine("Computing the texture size.");
    int size = -1;
    for (TextureData textureData : textureDatas) {
        if (textureData.texture instanceof Texture2D) {
            size = Math.max(textureData.texture.getImage().getWidth(), size);
            size = Math.max(textureData.texture.getImage().getHeight(), size);
        }
    }
    if (size < 0) {
        size = blenderContext.getBlenderKey().getSkyGeneratedTextureSize();
    }
    LOGGER.log(Level.FINE, "The sky texture size will be: {0}x{0}.", size);
    TextureCubeMap result = null;
    for (TextureData textureData : textureDatas) {
        TextureCubeMap texture = null;
        if (textureData.texture instanceof GeneratedTexture) {
            texture = ((GeneratedTexture) textureData.texture).generateSkyTexture(size, horizontalColor, zenithColor, blenderContext);
        } else {
            // first create a grayscale version of the image
            Image image = textureData.texture.getImage();
            if (image.getWidth() != image.getHeight() || image.getWidth() != size) {
                image = ImageUtils.resizeTo(image, size, size);
            }
            Image grayscaleImage = ImageUtils.convertToGrayscaleTexture(image);
            // add the sky colors to the image
            PixelInputOutput sourcePixelIO = PixelIOFactory.getPixelIO(grayscaleImage.getFormat());
            PixelInputOutput targetPixelIO = PixelIOFactory.getPixelIO(image.getFormat());
            TexturePixel texturePixel = new TexturePixel();
            for (int x = 0; x < image.getWidth(); ++x) {
                for (int y = 0; y < image.getHeight(); ++y) {
                    sourcePixelIO.read(grayscaleImage, 0, texturePixel, x, y);
                    // no matter which factor we use here, in grayscale they are all equal
                    texturePixel.intensity = texturePixel.red;
                    ImageUtils.color(texturePixel, horizontalColor, zenithColor);
                    targetPixelIO.write(image, 0, texturePixel, x, y);
                }
            }
            // create the cubemap texture from the coloured image
            ByteBuffer sourceData = image.getData(0);
            ArrayList<ByteBuffer> data = new ArrayList<ByteBuffer>(6);
            for (int i = 0; i < 6; ++i) {
                data.add(BufferUtils.clone(sourceData));
            }
            texture = new TextureCubeMap(new Image(image.getFormat(), image.getWidth(), image.getHeight(), 6, data, ColorSpace.Linear));
        }
        if (result == null) {
            result = texture;
        } else {
            ImageUtils.mix(result.getImage(), texture.getImage());
        }
    }
    return result;
}
Also used : Texture2D(com.jme3.texture.Texture2D) PixelInputOutput(com.jme3.scene.plugins.blender.textures.io.PixelInputOutput) TextureCubeMap(com.jme3.texture.TextureCubeMap) ArrayList(java.util.ArrayList) Image(com.jme3.texture.Image) BufferedImage(java.awt.image.BufferedImage) ByteBuffer(java.nio.ByteBuffer)

Aggregations

Spatial (com.jme3.scene.Spatial)123 Vector3f (com.jme3.math.Vector3f)74 Node (com.jme3.scene.Node)56 Geometry (com.jme3.scene.Geometry)50 DirectionalLight (com.jme3.light.DirectionalLight)46 Material (com.jme3.material.Material)39 Quaternion (com.jme3.math.Quaternion)34 FilterPostProcessor (com.jme3.post.FilterPostProcessor)17 Box (com.jme3.scene.shape.Box)17 KeyTrigger (com.jme3.input.controls.KeyTrigger)15 AmbientLight (com.jme3.light.AmbientLight)14 ColorRGBA (com.jme3.math.ColorRGBA)14 Camera (com.jme3.renderer.Camera)13 Sphere (com.jme3.scene.shape.Sphere)13 Texture (com.jme3.texture.Texture)12 TempVars (com.jme3.util.TempVars)12 InputCapsule (com.jme3.export.InputCapsule)11 ActionListener (com.jme3.input.controls.ActionListener)11 AnimControl (com.jme3.animation.AnimControl)10 OutputCapsule (com.jme3.export.OutputCapsule)9