Home | History | Annotate | Download | only in effect
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package com.jme3.effect;
     34 
     35 import com.jme3.math.Matrix3f;
     36 import com.jme3.renderer.Camera;
     37 import com.jme3.scene.VertexBuffer;
     38 import com.jme3.scene.VertexBuffer.Format;
     39 import com.jme3.scene.VertexBuffer.Usage;
     40 import com.jme3.util.BufferUtils;
     41 import java.nio.ByteBuffer;
     42 import java.nio.FloatBuffer;
     43 
     44 public class ParticlePointMesh extends ParticleMesh {
     45 
     46     private ParticleEmitter emitter;
     47 
     48     private int imagesX = 1;
     49     private int imagesY = 1;
     50 
     51     @Override
     52     public void setImagesXY(int imagesX, int imagesY) {
     53         this.imagesX = imagesX;
     54         this.imagesY = imagesY;
     55     }
     56 
     57     @Override
     58     public void initParticleData(ParticleEmitter emitter, int numParticles) {
     59         setMode(Mode.Points);
     60 
     61         this.emitter = emitter;
     62 
     63         // set positions
     64         FloatBuffer pb = BufferUtils.createVector3Buffer(numParticles);
     65         VertexBuffer pvb = new VertexBuffer(VertexBuffer.Type.Position);
     66         pvb.setupData(Usage.Stream, 3, Format.Float, pb);
     67 
     68         //if the buffer is already set only update the data
     69         VertexBuffer buf = getBuffer(VertexBuffer.Type.Position);
     70         if (buf != null) {
     71             buf.updateData(pb);
     72         } else {
     73             setBuffer(pvb);
     74         }
     75 
     76         // set colors
     77         ByteBuffer cb = BufferUtils.createByteBuffer(numParticles * 4);
     78         VertexBuffer cvb = new VertexBuffer(VertexBuffer.Type.Color);
     79         cvb.setupData(Usage.Stream, 4, Format.UnsignedByte, cb);
     80         cvb.setNormalized(true);
     81 
     82         buf = getBuffer(VertexBuffer.Type.Color);
     83         if (buf != null) {
     84             buf.updateData(cb);
     85         } else {
     86             setBuffer(cvb);
     87         }
     88 
     89         // set sizes
     90         FloatBuffer sb = BufferUtils.createFloatBuffer(numParticles);
     91         VertexBuffer svb = new VertexBuffer(VertexBuffer.Type.Size);
     92         svb.setupData(Usage.Stream, 1, Format.Float, sb);
     93 
     94         buf = getBuffer(VertexBuffer.Type.Size);
     95         if (buf != null) {
     96             buf.updateData(sb);
     97         } else {
     98             setBuffer(svb);
     99         }
    100 
    101         // set UV-scale
    102         FloatBuffer tb = BufferUtils.createFloatBuffer(numParticles*4);
    103         VertexBuffer tvb = new VertexBuffer(VertexBuffer.Type.TexCoord);
    104         tvb.setupData(Usage.Stream, 4, Format.Float, tb);
    105 
    106         buf = getBuffer(VertexBuffer.Type.TexCoord);
    107         if (buf != null) {
    108             buf.updateData(tb);
    109         } else {
    110             setBuffer(tvb);
    111         }
    112     }
    113 
    114     @Override
    115     public void updateParticleData(Particle[] particles, Camera cam, Matrix3f inverseRotation) {
    116         VertexBuffer pvb = getBuffer(VertexBuffer.Type.Position);
    117         FloatBuffer positions = (FloatBuffer) pvb.getData();
    118 
    119         VertexBuffer cvb = getBuffer(VertexBuffer.Type.Color);
    120         ByteBuffer colors = (ByteBuffer) cvb.getData();
    121 
    122         VertexBuffer svb = getBuffer(VertexBuffer.Type.Size);
    123         FloatBuffer sizes = (FloatBuffer) svb.getData();
    124 
    125         VertexBuffer tvb = getBuffer(VertexBuffer.Type.TexCoord);
    126         FloatBuffer texcoords = (FloatBuffer) tvb.getData();
    127 
    128         float sizeScale = emitter.getWorldScale().x;
    129 
    130         // update data in vertex buffers
    131         positions.rewind();
    132         colors.rewind();
    133         sizes.rewind();
    134         texcoords.rewind();
    135         for (int i = 0; i < particles.length; i++){
    136             Particle p = particles[i];
    137 
    138             positions.put(p.position.x)
    139                      .put(p.position.y)
    140                      .put(p.position.z);
    141 
    142             sizes.put(p.size * sizeScale);
    143             colors.putInt(p.color.asIntABGR());
    144 
    145             int imgX = p.imageIndex % imagesX;
    146             int imgY = (p.imageIndex - imgX) / imagesY;
    147 
    148             float startX = ((float) imgX) / imagesX;
    149             float startY = ((float) imgY) / imagesY;
    150             float endX   = startX + (1f / imagesX);
    151             float endY   = startY + (1f / imagesY);
    152 
    153             texcoords.put(startX).put(startY).put(endX).put(endY);
    154         }
    155         positions.flip();
    156         colors.flip();
    157         sizes.flip();
    158         texcoords.flip();
    159 
    160         // force renderer to re-send data to GPU
    161         pvb.updateData(positions);
    162         cvb.updateData(colors);
    163         svb.updateData(sizes);
    164         tvb.updateData(texcoords);
    165     }
    166 }
    167