@ -33,15 +33,22 @@ package com.jme3.effect;
import com.jme3.math.Matrix3f ;
import com.jme3.renderer.Camera ;
import com.jme3.renderer.RenderManager ;
import com.jme3.scene.VertexBuffer ;
import com.jme3.scene.VertexBuffer.Format ;
import com.jme3.scene.VertexBuffer.Usage ;
import com.jme3.util.BufferUtils ;
import com.jme3.util.TempVars ;
import java.nio.ByteBuffer ;
import java.nio.FloatBuffer ;
public class ParticlePointMesh extends ParticleMesh {
private static final int POS_SIZE = 3 * 4 ;
private static final int COLOR_SIZE = 4 * 1 ;
private static final int SIZE_SIZE = 1 * 4 ;
private static final int UV_SIZE = 4 * 4 ;
private static final int TOTAL_SIZE = POS_SIZE + COLOR_SIZE + SIZE_SIZE + UV_SIZE ;
private ParticleEmitter emitter ;
private int imagesX = 1 ;
@ -59,109 +66,86 @@ public class ParticlePointMesh extends ParticleMesh {
this . emitter = emitter ;
// set positions
FloatBuffer pb = BufferUtils . createVector3Buffer ( numParticles ) ;
//if the buffer is already set only update the data
VertexBuffer buf = getBuffer ( VertexBuffer . Type . Position ) ;
if ( buf ! = null ) {
buf . updateData ( pb ) ;
} else {
VertexBuffer pvb = new VertexBuffer ( VertexBuffer . Type . Position ) ;
pvb . setupData ( Usage . Stream , 3 , Format . Float , pb ) ;
setBuffer ( pvb ) ;
}
// set colors
ByteBuffer cb = BufferUtils . createByteBuffer ( numParticles * 4 ) ;
buf = getBuffer ( VertexBuffer . Type . Color ) ;
if ( buf ! = null ) {
buf . updateData ( cb ) ;
} else {
VertexBuffer cvb = new VertexBuffer ( VertexBuffer . Type . Color ) ;
cvb . setupData ( Usage . Stream , 4 , Format . UnsignedByte , cb ) ;
cvb . setNormalized ( true ) ;
setBuffer ( cvb ) ;
}
ByteBuffer eb = BufferUtils . createByteBuffer ( TOTAL_SIZE * numParticles ) ;
VertexBuffer vb = new VertexBuffer ( VertexBuffer . Type . InterleavedData ) ;
vb . setupData ( Usage . Stream , 1 , Format . Byte , eb ) ;
setBuffer ( vb ) ;
VertexBuffer pb = new VertexBuffer ( VertexBuffer . Type . Position ) ;
pb . setupData ( Usage . Stream , 3 , Format . Float , eb ) ;
pb . updateData ( null ) ;
pb . setOffset ( 0 ) ;
pb . setStride ( TOTAL_SIZE ) ;
setBuffer ( pb ) ;
VertexBuffer cb = new VertexBuffer ( VertexBuffer . Type . Color ) ;
cb . setupData ( Usage . Stream , 4 , Format . UnsignedByte , eb ) ;
cb . updateData ( null ) ;
cb . setNormalized ( true ) ;
cb . setOffset ( POS_SIZE ) ;
cb . setStride ( TOTAL_SIZE ) ;
setBuffer ( cb ) ;
VertexBuffer sb = new VertexBuffer ( VertexBuffer . Type . Size ) ;
sb . setupData ( Usage . Stream , 1 , Format . Float , eb ) ;
sb . updateData ( null ) ;
sb . setOffset ( POS_SIZE + COLOR_SIZE ) ;
sb . setStride ( TOTAL_SIZE ) ;
setBuffer ( sb ) ;
VertexBuffer tb = new VertexBuffer ( VertexBuffer . Type . TexCoord ) ;
tb . setupData ( Usage . Stream , 4 , Format . Float , eb ) ;
tb . updateData ( null ) ;
tb . setOffset ( POS_SIZE + COLOR_SIZE + SIZE_SIZE ) ;
tb . setStride ( TOTAL_SIZE ) ;
setBuffer ( tb ) ;
// set sizes
FloatBuffer sb = BufferUtils . createFloatBuffer ( numParticles ) ;
buf = getBuffer ( VertexBuffer . Type . Size ) ;
if ( buf ! = null ) {
buf . updateData ( sb ) ;
} else {
VertexBuffer svb = new VertexBuffer ( VertexBuffer . Type . Size ) ;
svb . setupData ( Usage . Stream , 1 , Format . Float , sb ) ;
setBuffer ( svb ) ;
}
// set UV-scale
FloatBuffer tb = BufferUtils . createFloatBuffer ( numParticles * 4 ) ;
buf = getBuffer ( VertexBuffer . Type . TexCoord ) ;
if ( buf ! = null ) {
buf . updateData ( tb ) ;
} else {
VertexBuffer tvb = new VertexBuffer ( VertexBuffer . Type . TexCoord ) ;
tvb . setupData ( Usage . Stream , 4 , Format . Float , tb ) ;
setBuffer ( tvb ) ;
}
updateCounts ( ) ;
}
@Override
public void updateParticleData ( Particle [ ] particles , Camera cam , Matrix3f inverseRotation ) {
VertexBuffer pv b = getBuffer ( VertexBuffer . Type . Position ) ;
FloatBuffer positions = ( FloatBuffer ) pv b. getData ( ) ;
public void updateParticleData ( RenderManager rm , Particle [ ] particles , Camera cam , Matrix3f inverseRotation ) {
VertexBuffer eb = getBuffer ( VertexBuffer . Type . InterleavedData ) ;
ByteBuffer elements = ( ByteBuffer ) eb . getData ( ) ;
VertexBuffer cvb = getBuffer ( VertexBuffer . Type . Color ) ;
ByteBuffer colors = ( ByteBuffer ) cvb . getData ( ) ;
float sizeScale = emitter . getWorldScale ( ) . x ;
VertexBuffer svb = getBuffer ( VertexBuffer . Type . Size ) ;
FloatBuffer sizes = ( FloatBuffer ) svb . getData ( ) ;
TempVars vars = TempVars . get ( ) ;
try {
float [ ] temp = vars . skinTangents ;
int index = 0 ;
VertexBuffer tvb = getBuffer ( VertexBuffer . Type . TexCoord ) ;
FloatBuffer texcoords = ( FloatBuffer ) tvb . getData ( ) ;
for ( int i = 0 ; i < particles . length ; i + + ) {
Particle p = particles [ i ] ;
float sizeScale = emitter . getWorldScale ( ) . x ;
temp [ index + + ] = p . position . x ;
temp [ index + + ] = p . position . y ;
temp [ index + + ] = p . position . z ;
temp [ index + + ] = Float . intBitsToFloat ( p . color . asIntABGR ( ) ) ;
temp [ index + + ] = p . size * sizeScale ;
int imgX = p . imageIndex % imagesX ;
int imgY = ( p . imageIndex - imgX ) / imagesY ;
float startX = ( ( float ) imgX ) / imagesX ;
float startY = ( ( float ) imgY ) / imagesY ;
float endX = startX + ( 1f / imagesX ) ;
float endY = startY + ( 1f / imagesY ) ;
temp [ index + + ] = startX ;
temp [ index + + ] = startY ;
temp [ index + + ] = endX ;
temp [ index + + ] = endY ;
}
elements . asFloatBuffer ( ) . put ( temp , 0 , ( TOTAL_SIZE / 4 ) * particles . length ) . flip ( ) ;
eb . updateData ( elements ) ;
// update data in vertex buffers
positions . rewind ( ) ;
colors . rewind ( ) ;
sizes . rewind ( ) ;
texcoords . rewind ( ) ;
for ( int i = 0 ; i < particles . length ; i + + ) {
Particle p = particles [ i ] ;
positions . put ( p . position . x )
. put ( p . position . y )
. put ( p . position . z ) ;
sizes . put ( p . size * sizeScale ) ;
colors . putInt ( p . color . asIntABGR ( ) ) ;
int imgX = p . imageIndex % imagesX ;
int imgY = ( p . imageIndex - imgX ) / imagesY ;
float startX = ( ( float ) imgX ) / imagesX ;
float startY = ( ( float ) imgY ) / imagesY ;
float endX = startX + ( 1f / imagesX ) ;
float endY = startY + ( 1f / imagesY ) ;
texcoords . put ( startX ) . put ( startY ) . put ( endX ) . put ( endY ) ;
// cheating!
rm . getRenderer ( ) . updateBufferData ( eb ) ;
} finally {
vars . release ( ) ;
}
positions . flip ( ) ;
colors . flip ( ) ;
sizes . flip ( ) ;
texcoords . flip ( ) ;
// force renderer to re-send data to GPU
pvb . updateData ( positions ) ;
cvb . updateData ( colors ) ;
svb . updateData ( sizes ) ;
tvb . updateData ( texcoords ) ;
}
}