Search in sources :

Example 16 with Edge

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

the class TemporalMesh method clone.

@Override
public TemporalMesh clone() {
    try {
        TemporalMesh result = new TemporalMesh(meshStructure, blenderContext, false);
        result.name = name;
        for (Vector3f v : vertices) {
            result.vertices.add(v.clone());
        }
        for (Vector3f n : normals) {
            result.normals.add(n.clone());
        }
        for (Map<String, Float> group : vertexGroups) {
            result.vertexGroups.add(new HashMap<String, Float>(group));
        }
        for (byte[] vertColor : verticesColors) {
            result.verticesColors.add(vertColor.clone());
        }
        result.materials = materials;
        result.properties = properties;
        result.boneIndexes.putAll(boneIndexes);
        result.postMeshCreationModifiers.addAll(postMeshCreationModifiers);
        for (Face face : faces) {
            result.faces.add(face.clone());
        }
        for (Edge edge : edges) {
            result.edges.add(edge.clone());
        }
        for (Point point : points) {
            result.points.add(point.clone());
        }
        result.rebuildIndexesMappings();
        return result;
    } catch (BlenderFileException e) {
        LOGGER.log(Level.SEVERE, "Error while cloning the temporal mesh: {0}. Returning null.", e.getLocalizedMessage());
    }
    return null;
}
Also used : Vector3f(com.jme3.math.Vector3f) BlenderFileException(com.jme3.scene.plugins.blender.file.BlenderFileException)

Example 17 with Edge

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

the class MaskModifier method removeVertexAt.

/**
     * Every face, edge and point that contains
     * the vertex will be removed.
     * @param index
     *            the index of a vertex to be removed
     * @throws IndexOutOfBoundsException
     *             thrown when given index is negative or beyond the count of vertices
     */
private void removeVertexAt(final int index, TemporalMesh temporalMesh) {
    if (index < 0 || index >= temporalMesh.getVertexCount()) {
        throw new IndexOutOfBoundsException("The given index is out of bounds: " + index);
    }
    temporalMesh.getVertices().remove(index);
    temporalMesh.getNormals().remove(index);
    if (temporalMesh.getVertexGroups().size() > 0) {
        temporalMesh.getVertexGroups().remove(index);
    }
    if (temporalMesh.getVerticesColors().size() > 0) {
        temporalMesh.getVerticesColors().remove(index);
    }
    IndexPredicate shiftPredicate = new IndexPredicate() {

        @Override
        public boolean execute(Integer i) {
            return i > index;
        }
    };
    for (int i = temporalMesh.getFaces().size() - 1; i >= 0; --i) {
        Face face = temporalMesh.getFaces().get(i);
        if (face.getIndexes().indexOf(index) >= 0) {
            temporalMesh.getFaces().remove(i);
        } else {
            face.getIndexes().shiftIndexes(-1, shiftPredicate);
        }
    }
    for (int i = temporalMesh.getEdges().size() - 1; i >= 0; --i) {
        Edge edge = temporalMesh.getEdges().get(i);
        if (edge.getFirstIndex() == index || edge.getSecondIndex() == index) {
            temporalMesh.getEdges().remove(i);
        } else {
            edge.shiftIndexes(-1, shiftPredicate);
        }
    }
    for (int i = temporalMesh.getPoints().size() - 1; i >= 0; --i) {
        Point point = temporalMesh.getPoints().get(i);
        if (point.getIndex() == index) {
            temporalMesh.getPoints().remove(i);
        } else {
            point.shiftIndexes(-1, shiftPredicate);
        }
    }
}
Also used : IndexPredicate(com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate) Point(com.jme3.scene.plugins.blender.meshes.Point) Face(com.jme3.scene.plugins.blender.meshes.Face) Edge(com.jme3.scene.plugins.blender.meshes.Edge) Point(com.jme3.scene.plugins.blender.meshes.Point)

Example 18 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge 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 19 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge 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 20 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge 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

Vector3f (com.jme3.math.Vector3f)17 ArrayList (java.util.ArrayList)7 Edge (com.jme3.scene.plugins.blender.meshes.Edge)5 Face (com.jme3.scene.plugins.blender.meshes.Face)5 Test (org.junit.Test)5 BoundingBox (com.jme3.bounding.BoundingBox)3 BoundingSphere (com.jme3.bounding.BoundingSphere)3 Structure (com.jme3.scene.plugins.blender.file.Structure)3 TempVars (com.jme3.util.TempVars)3 Node (com.jme3.scene.Node)2 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)2 Pointer (com.jme3.scene.plugins.blender.file.Pointer)2 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2 List (java.util.List)2 CollisionResult (com.jme3.collision.CollisionResult)1 DirectionalLight (com.jme3.light.DirectionalLight)1 PointLight (com.jme3.light.PointLight)1 SpotLight (com.jme3.light.SpotLight)1 Plane (com.jme3.math.Plane)1