Search in sources :

Example 16 with TemporalMesh

use of com.jme3.scene.plugins.blender.meshes.TemporalMesh in project jmonkeyengine by jMonkeyEngine.

the class Face method clone.

@Override
public Face clone() {
    Face result = new Face();
    result.indexes = indexes.clone();
    result.smooth = smooth;
    result.materialNumber = materialNumber;
    if (faceUVCoords != null) {
        result.faceUVCoords = new HashMap<String, List<Vector2f>>(faceUVCoords.size());
        for (Entry<String, List<Vector2f>> entry : faceUVCoords.entrySet()) {
            List<Vector2f> uvs = new ArrayList<Vector2f>(entry.getValue().size());
            for (Vector2f v : entry.getValue()) {
                uvs.add(v.clone());
            }
            result.faceUVCoords.put(entry.getKey(), uvs);
        }
    }
    if (vertexColors != null) {
        result.vertexColors = new ArrayList<byte[]>(vertexColors.size());
        for (byte[] colors : vertexColors) {
            result.vertexColors.add(colors.clone());
        }
    }
    result.temporalMesh = temporalMesh;
    return result;
}
Also used : Vector2f(com.jme3.math.Vector2f) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 17 with TemporalMesh

use of com.jme3.scene.plugins.blender.meshes.TemporalMesh in project jmonkeyengine by jMonkeyEngine.

the class Face method contains.

/**
     * The method verifies if the edge is contained within the face.
     * It means it cannot cross any other edge and it must be inside the face and not outside of it.
     * @param edge
     *            the edge to be checked
     * @return <b>true</b> if the given edge is contained within the face and <b>false</b> otherwise
     */
private boolean contains(Edge edge) {
    int index1 = edge.getFirstIndex();
    int index2 = edge.getSecondIndex();
    // check if the line between the vertices is not a border edge of the face
    if (!indexes.areNeighbours(index1, index2)) {
        for (int i = 0; i < indexes.size(); ++i) {
            int i1 = this.getIndex(i - 1);
            int i2 = this.getIndex(i);
            // check if the edges have no common verts (because if they do, they cannot cross)
            if (i1 != index1 && i1 != index2 && i2 != index1 && i2 != index2) {
                if (edge.cross(new Edge(i1, i2, 0, false, temporalMesh))) {
                    return false;
                }
            }
        }
        // computing the edge's middle point
        Vector3f edgeMiddlePoint = edge.computeCentroid();
        // computing the edge that is perpendicular to the given edge and has a length of 1 (length actually does not matter)
        Vector3f edgeVector = edge.getSecondVertex().subtract(edge.getFirstVertex());
        Vector3f edgeNormal = temporalMesh.getNormals().get(index1).cross(edgeVector).normalizeLocal();
        Edge e = new Edge(edgeMiddlePoint, edgeNormal.add(edgeMiddlePoint));
        // compute the vectors from the middle point to the crossing between the extended edge 'e' and other edges of the face
        List<Vector3f> crossingVectors = new ArrayList<Vector3f>();
        for (int i = 0; i < indexes.size(); ++i) {
            int i1 = this.getIndex(i);
            int i2 = this.getIndex(i + 1);
            Vector3f crossPoint = e.getCrossPoint(new Edge(i1, i2, 0, false, temporalMesh), true, false);
            if (crossPoint != null) {
                crossingVectors.add(crossPoint.subtractLocal(edgeMiddlePoint));
            }
        }
        if (crossingVectors.size() == 0) {
            // edges do not cross
            return false;
        }
        // use only distinct vertices (doubles may appear if the crossing point is a vertex)
        List<Vector3f> distinctCrossingVectors = new ArrayList<Vector3f>();
        for (Vector3f cv : crossingVectors) {
            double minDistance = Double.MAX_VALUE;
            for (Vector3f dcv : distinctCrossingVectors) {
                minDistance = Math.min(minDistance, dcv.distance(cv));
            }
            if (minDistance > FastMath.FLT_EPSILON) {
                distinctCrossingVectors.add(cv);
            }
        }
        if (distinctCrossingVectors.size() == 0) {
            throw new IllegalStateException("There MUST be at least 2 crossing vertices!");
        }
        // checking if all crossing vectors point to the same direction (if yes then the edge is outside the face)
        // if at least one vector has different direction that this - it means that the edge is inside the face
        float direction = Math.signum(distinctCrossingVectors.get(0).dot(edgeNormal));
        for (int i = 1; i < distinctCrossingVectors.size(); ++i) {
            if (direction != Math.signum(distinctCrossingVectors.get(i).dot(edgeNormal))) {
                return true;
            }
        }
        return false;
    }
    return true;
}
Also used : Vector3f(com.jme3.math.Vector3f) ArrayList(java.util.ArrayList)

Example 18 with TemporalMesh

use of com.jme3.scene.plugins.blender.meshes.TemporalMesh in project jmonkeyengine by jMonkeyEngine.

the class Face method findClosestVertex.

/**
	 * The method finds the closest vertex to the one specified by <b>index</b>.
	 * If the vertexToIgnore is positive than it will be ignored in the result.
	 * The closest vertex must be able to create an edge that is fully contained
	 * within the face and does not cross any other edges. Also if the
	 * vertexToIgnore is not negative then the condition that the edge between
	 * the found index and the one to ignore is inside the face must also be
	 * met.
	 * 
	 * @param index
	 *            the index of the vertex that needs to have found the nearest
	 *            neighbour
	 * @param indexToIgnore
	 *            the index to ignore in the result (pass -1 if none is to be
	 *            ignored)
	 * @return the index of the closest vertex to the given one
	 */
private int findClosestVertex(int index, int indexToIgnore) {
    int result = -1;
    List<Vector3f> vertices = temporalMesh.getVertices();
    Vector3f v1 = vertices.get(index);
    float distance = Float.MAX_VALUE;
    for (int i : indexes) {
        if (i != index && i != indexToIgnore) {
            Vector3f v2 = vertices.get(i);
            float d = v2.distance(v1);
            if (d < distance && this.contains(new Edge(index, i, 0, true, temporalMesh)) && (indexToIgnore < 0 || this.contains(new Edge(indexToIgnore, i, 0, true, temporalMesh)))) {
                result = i;
                distance = d;
            }
        }
    }
    return result;
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 19 with TemporalMesh

use of com.jme3.scene.plugins.blender.meshes.TemporalMesh in project jmonkeyengine by jMonkeyEngine.

the class TriangulateModifier method apply.

@Override
public void apply(Node node, BlenderContext blenderContext) {
    if (invalid) {
        LOGGER.log(Level.WARNING, "Triangulate modifier is invalid! Cannot be applied to: {0}", node.getName());
    }
    TemporalMesh temporalMesh = this.getTemporalMesh(node);
    if (temporalMesh != null) {
        LOGGER.log(Level.FINE, "Applying triangulation modifier to: {0}", temporalMesh);
        temporalMesh.triangulate();
    } else {
        LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node);
    }
}
Also used : TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh)

Example 20 with TemporalMesh

use of com.jme3.scene.plugins.blender.meshes.TemporalMesh in project jmonkeyengine by jMonkeyEngine.

the class Edge method loadAll.

/**
     * The method loads all edges from the given mesh structure that does not belong to any face.
     * @param meshStructure
     *            the mesh structure
     * @param temporalMesh
     *            the owner of the edges
     * @return all edges without faces
     * @throws BlenderFileException
     *             an exception is thrown when problems with file reading occur
     */
public static List<Edge> loadAll(Structure meshStructure, TemporalMesh temporalMesh) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Loading all edges that do not belong to any face from mesh: {0}", meshStructure.getName());
    List<Edge> result = new ArrayList<Edge>();
    Pointer pMEdge = (Pointer) meshStructure.getFieldValue("medge");
    if (pMEdge.isNotNull()) {
        List<Structure> edges = pMEdge.fetchData();
        for (Structure edge : edges) {
            int flag = ((Number) edge.getFieldValue("flag")).intValue();
            int v1 = ((Number) edge.getFieldValue("v1")).intValue();
            int v2 = ((Number) edge.getFieldValue("v2")).intValue();
            // I do not know why, but blender stores (possibly only sometimes) crease as negative values and shows positive in the editor
            float crease = Math.abs(((Number) edge.getFieldValue("crease")).floatValue());
            boolean edgeInFace = (flag & Edge.FLAG_EDGE_NOT_IN_FACE) == 0;
            result.add(new Edge(v1, v2, crease, edgeInFace, temporalMesh));
        }
    }
    LOGGER.log(Level.FINE, "Loaded {0} edges.", result.size());
    return result;
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure)

Aggregations

ArrayList (java.util.ArrayList)11 TemporalMesh (com.jme3.scene.plugins.blender.meshes.TemporalMesh)10 Vector3f (com.jme3.math.Vector3f)8 Structure (com.jme3.scene.plugins.blender.file.Structure)7 List (java.util.List)7 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)6 Pointer (com.jme3.scene.plugins.blender.file.Pointer)5 Face (com.jme3.scene.plugins.blender.meshes.Face)5 Vector2f (com.jme3.math.Vector2f)4 Node (com.jme3.scene.Node)4 Edge (com.jme3.scene.plugins.blender.meshes.Edge)4 HashMap (java.util.HashMap)4 Light (com.jme3.light.Light)3 MeshHelper (com.jme3.scene.plugins.blender.meshes.MeshHelper)3 ObjectHelper (com.jme3.scene.plugins.blender.objects.ObjectHelper)3 Texture (com.jme3.texture.Texture)3 Map (java.util.Map)3 BoundingBox (com.jme3.bounding.BoundingBox)2 Filter (com.jme3.post.Filter)2 Camera (com.jme3.renderer.Camera)2