From b6d7b78a70be7d61113227c9209ca83f0f38071b Mon Sep 17 00:00:00 2001 From: "Kae..pl" Date: Thu, 19 May 2011 20:30:08 +0000 Subject: [PATCH] Added shape emitters that uste the meshes' shapes to emit particles (used by Blender Loader). git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7511 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../effect/EmitterMeshConvexHullShape.java | 36 +++++++++ .../com/jme3/effect/EmitterMeshFaceShape.java | 43 +++++++++++ .../jme3/effect/EmitterMeshVertexShape.java | 77 +++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 engine/src/core/com/jme3/effect/EmitterMeshConvexHullShape.java create mode 100644 engine/src/core/com/jme3/effect/EmitterMeshFaceShape.java create mode 100644 engine/src/core/com/jme3/effect/EmitterMeshVertexShape.java diff --git a/engine/src/core/com/jme3/effect/EmitterMeshConvexHullShape.java b/engine/src/core/com/jme3/effect/EmitterMeshConvexHullShape.java new file mode 100644 index 000000000..0fe3dbc04 --- /dev/null +++ b/engine/src/core/com/jme3/effect/EmitterMeshConvexHullShape.java @@ -0,0 +1,36 @@ +package com.jme3.effect; + +import java.util.List; + +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Mesh; + +/** + * This emiter shape emits the particles from the given shape's interior constrained by its convex hull + * (a geometry that tightly wraps the mesh). So in case of multiple meshes some vertices may appear + * in a space between them. + * @author Marcin Roguski (Kaelthas) + */ +public class EmitterMeshConvexHullShape extends EmitterMeshFaceShape { + /** + * Empty constructor. Sets nothing. + */ + public EmitterMeshConvexHullShape() {} + + /** + * Constructor. It stores a copy of vertex list of all meshes. + * @param meshes a list of meshes that will form the emitter's shape + */ + public EmitterMeshConvexHullShape(List meshes) { + super(meshes); + } + + @Override + public void getRandomPoint(Vector3f store) { + super.getRandomPoint(store); + //now move the point from the meshe's face towards the center of the mesh + //the center is in (0, 0, 0) in the local coordinates + store.multLocal(FastMath.nextRandomFloat()); + } +} diff --git a/engine/src/core/com/jme3/effect/EmitterMeshFaceShape.java b/engine/src/core/com/jme3/effect/EmitterMeshFaceShape.java new file mode 100644 index 000000000..d9c6f7094 --- /dev/null +++ b/engine/src/core/com/jme3/effect/EmitterMeshFaceShape.java @@ -0,0 +1,43 @@ +package com.jme3.effect; + +import java.util.List; + +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Mesh; + +/** + * This emiter shape emits the particles from the given shape's faces. + * @author Marcin Roguski (Kaelthas) + */ +public class EmitterMeshFaceShape extends EmitterMeshVertexShape { + /** + * Empty constructor. Sets nothing. + */ + public EmitterMeshFaceShape() {} + + /** + * Constructor. It stores a copy of vertex list of all meshes. + * @param meshes a list of meshes that will form the emitter's shape + */ + public EmitterMeshFaceShape(List meshes) { + super(meshes); + } + + @Override + public void getRandomPoint(Vector3f store) { + int meshIndex = FastMath.nextRandomInt(0, vertices.length-1); + //the index of the first vertex of a face (must be dividable by 9) + int vertIndex = FastMath.nextRandomInt(0, vertices[meshIndex].length / 9 - 1) * 9; + //put the point somewhere between the first and the second vertex of a face + float moveFactor = FastMath.nextRandomFloat(); + store.set(vertices[meshIndex][vertIndex] + (vertices[meshIndex][vertIndex + 3] - vertices[meshIndex][vertIndex]) * moveFactor, + vertices[meshIndex][vertIndex + 1] + (vertices[meshIndex][vertIndex + 4] - vertices[meshIndex][vertIndex + 1]) * moveFactor, + vertices[meshIndex][vertIndex + 2] + (vertices[meshIndex][vertIndex + 5] - vertices[meshIndex][vertIndex + 2]) * moveFactor); + //move the result towards the last face vertex + moveFactor = FastMath.nextRandomFloat(); + store.addLocal((vertices[meshIndex][vertIndex + 6] - store.x) * moveFactor, + (vertices[meshIndex][vertIndex + 7] - store.y) * moveFactor, + (vertices[meshIndex][vertIndex + 8] - store.z) * moveFactor); + } +} diff --git a/engine/src/core/com/jme3/effect/EmitterMeshVertexShape.java b/engine/src/core/com/jme3/effect/EmitterMeshVertexShape.java new file mode 100644 index 000000000..2a46327b0 --- /dev/null +++ b/engine/src/core/com/jme3/effect/EmitterMeshVertexShape.java @@ -0,0 +1,77 @@ +package com.jme3.effect; + +import java.io.IOException; +import java.nio.FloatBuffer; +import java.util.List; + +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.util.BufferUtils; + +/** + * This emiter shape emits the particles from the given shape's vertices + * @author Marcin Roguski (Kaelthas) + */ +public class EmitterMeshVertexShape implements EmitterShape { + protected float[][] vertices; + + /** + * Empty constructor. Sets nothing. + */ + public EmitterMeshVertexShape() {} + + /** + * Constructor. It stores a copy of vertex list of all meshes. + * @param meshes a list of meshes that will form the emitter's shape + */ + public EmitterMeshVertexShape(List meshes) { + this.setMeshes(meshes); + } + + /** + * This method sets the meshes that will form the emiter's shape. + * @param meshes a list of meshes that will form the emitter's shape + */ + public void setMeshes(List meshes) { + this.vertices = new float[meshes.size()][]; + int i=0; + for(Mesh mesh : meshes) { + FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position); + vertices[i++] = BufferUtils.getFloatArray(floatBuffer); + } + } + + @Override + public void getRandomPoint(Vector3f store) { + int meshIndex = FastMath.nextRandomInt(0, vertices.length-1); + int vertIndex = FastMath.nextRandomInt(0, vertices[meshIndex].length / 3 - 1) * 3; + store.set(vertices[meshIndex][vertIndex], vertices[meshIndex][vertIndex + 1], vertices[meshIndex][vertIndex + 2]); + } + + @Override + public EmitterShape deepClone() { + try { + EmitterMeshVertexShape clone = (EmitterMeshVertexShape) super.clone(); + clone.vertices = vertices==null ? null : vertices.clone(); + return clone; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + @Override + public void write(JmeExporter ex) throws IOException { + OutputCapsule oc = ex.getCapsule(this); + oc.write(vertices, "vertices", null); + } + + @Override + public void read(JmeImporter im) throws IOException { + this.vertices = im.getCapsule(this).readFloatArray2D("vertices", null); + } +}