📄 particle.java
字号:
/*
* Copyright (c) 2003-2009 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jmex.effects.particles;
import java.io.IOException;
import java.nio.FloatBuffer;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Triangle;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;
import com.jme.util.export.Savable;
import com.jme.util.geom.BufferUtils;
import com.jmex.effects.particles.ParticleSystem.ParticleType;
/**
* <code>Particle</code> defines a single Particle of a Particle system.
* Generally, you would not interact with this class directly.
*
* @author Joshua Slack
* @version $Id: Particle.java,v 1.10 2007/09/21 15:45:32 nca Exp $
*/
public class Particle implements Savable {
public enum Status {
/** Particle is dead -- not in play. */
Dead,
/** Particle is currently active. */
Alive,
/** Particle is available for spawning. */
Available;
}
static final int VAL_CURRENT_SIZE = 0;
static final int VAL_CURRENT_SPIN = 1;
static final int VAL_CURRENT_MASS = 2;
private int startIndex;
private Vector3f position;
private ColorRGBA currColor = ColorRGBA.black.clone();
private Status status = Status.Available;
private float lifeSpan;
private float[] values = new float[3];
private int currentAge;
private int currentTexIndex = -1;
private ParticleSystem parent;
private Vector3f velocity;
private Vector3f bbX = new Vector3f(), bbY = new Vector3f();
// colors
private ParticleType type = ParticleSystem.ParticleType.Quad;
private Triangle triModel;
// static variable for use in calculations to eliminate object creation
private static Vector3f tempVec3 = new Vector3f();
private static Quaternion tempQuat = new Quaternion();
/**
* Empty constructor - mostly for use with Savable interface
*/
public Particle() {
}
/**
* Normal use constructor. Sets up the parent and particle type for this
* particle.
*
* @param parent
* the particle collection this particle belongs to
*/
public Particle(ParticleSystem parent) {
this.parent = parent;
this.type = parent.getParticleType();
}
/**
* Cause this particle to reset it's lifespan, velocity, color, age and size
* per the parent's settings. status is set to Status.Available and location
* is set to 0,0,0. Actual geometry data is not affected by this call, only
* particle params.
*/
public void init() {
init(parent.getRandomVelocity(null), new Vector3f(), parent
.getRandomLifeSpan());
}
/**
* Cause this particle to reset it's color, age and size per the parent's
* settings. status is set to Status.Available. Location, velocity and
* lifespan are set as given. Actual geometry data is not affected by this
* call, only particle params.
*
* @param velocity
* new initial particle velocity
* @param position
* new initial particle position
* @param lifeSpan
* new particle lifespan in ms
*/
public void init(Vector3f velocity, Vector3f position, float lifeSpan) {
this.lifeSpan = lifeSpan;
this.velocity = (Vector3f) velocity.clone();
this.position = (Vector3f) position.clone();
currColor.set(parent.getStartColor());
currentAge = 0;
status = Status.Available;
values[VAL_CURRENT_SIZE] = parent.getStartSize();
}
/**
* Reset particle conditions. Besides the passed lifespan, we also reset
* color, size, and spin angle to their starting values (as given by
* parent.) Status is set to Status.Available.
*
* @param lifeSpan
* the recreated particle's new lifespan
*/
public void recreateParticle(float lifeSpan) {
this.lifeSpan = lifeSpan;
int verts = ParticleSystem.getVertsForParticleType(type);
currColor.set(parent.getStartColor());
for (int x = 0; x < verts; x++)
BufferUtils.setInBuffer(currColor, parent.getParticleGeometry()
.getColorBuffer(), startIndex + x);
values[VAL_CURRENT_SIZE] = parent.getStartSize();
currentAge = 0;
values[VAL_CURRENT_MASS] = 1;
status = Status.Available;
}
/**
* Update the vertices for this particle, taking size, spin and viewer into
* consideration. In the case of particle type ParticleType.GeomMesh, the
* original triangle normal is maintained rather than rotating it to face
* the camera or parent vectors.
*
* @param cam
* Camera to use in determining viewer aspect. If null, or if
* parent is not set to camera facing, parent's left and up
* vectors are used.
*/
public void updateVerts(Camera cam) {
float orient = parent.getParticleOrientation()
+ values[VAL_CURRENT_SPIN];
float currSize = values[VAL_CURRENT_SIZE];
if (type == ParticleSystem.ParticleType.GeomMesh
|| type == ParticleSystem.ParticleType.Point) {
; // nothing to do
} else if (cam != null && parent.isCameraFacing()) {
if (parent.isVelocityAligned()) {
bbX.set(velocity).normalizeLocal().multLocal(currSize);
cam.getDirection().cross(bbX, bbY).normalizeLocal().multLocal(
currSize);
} else if (orient == 0) {
bbX.set(cam.getLeft()).multLocal(currSize);
bbY.set(cam.getUp()).multLocal(currSize);
} else {
float cA = FastMath.cos(orient) * currSize;
float sA = FastMath.sin(orient) * currSize;
bbX.set(cam.getLeft()).multLocal(cA).addLocal(
cam.getUp().x * sA, cam.getUp().y * sA,
cam.getUp().z * sA);
bbY.set(cam.getLeft()).multLocal(-sA).addLocal(
cam.getUp().x * cA, cam.getUp().y * cA,
cam.getUp().z * cA);
}
} else {
bbX.set(parent.getLeftVector()).multLocal(currSize);
bbY.set(parent.getUpVector()).multLocal(currSize);
}
switch (type) {
case Quad: {
position.add(bbX, tempVec3).subtractLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex);
position.add(bbX, tempVec3).addLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 1);
position.subtract(bbX, tempVec3).subtractLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 2);
position.subtract(bbX, tempVec3).addLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 3);
break;
}
case GeomMesh: {
Vector3f norm = triModel.getNormal();
if (orient != 0)
tempQuat.fromAngleNormalAxis(orient, norm);
for (int x = 0; x < 3; x++) {
if (orient != 0)
tempQuat.mult(triModel.get(x), tempVec3);
else
tempVec3.set(triModel.get(x));
tempVec3.multLocal(currSize).addLocal(position);
BufferUtils.setInBuffer(tempVec3, parent
.getParticleGeometry().getVertexBuffer(),
startIndex + x);
}
break;
}
case Triangle: {
position.add(bbX, tempVec3).subtractLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex);
position.add(bbX, tempVec3).addLocal(3 * bbY.x, 3 * bbY.y,
3 * bbY.z);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 1);
position.subtract(bbX.multLocal(3), tempVec3).subtractLocal(bbY);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 2);
break;
}
case Line: {
position.subtract(bbX, tempVec3);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex);
position.add(bbX, tempVec3);
BufferUtils.setInBuffer(tempVec3, parent.getParticleGeometry()
.getVertexBuffer(), startIndex + 1);
break;
}
case Point: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -