⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 particle.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -