• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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