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 setImagesXY(int imagesX, int imagesY)52 public void setImagesXY(int imagesX, int imagesY) { 53 this.imagesX = imagesX; 54 this.imagesY = imagesY; 55 } 56 57 @Override initParticleData(ParticleEmitter emitter, int numParticles)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 updateParticleData(Particle[] particles, Camera cam, Matrix3f inverseRotation)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