@Override protected void flush(int[] offsets) { int tp = 0; for (PointSpriteControllerRenderData data : renderData) { FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel = data.rotationChannel; for (int p = 0; p < data.controller.particles.size; ++p, ++tp) { int offset = offsets[tp] * CPU_VERTEX_SIZE; int regionOffset = p * regionChannel.strideSize; int positionOffset = p * positionChannel.strideSize; int colorOffset = p * colorChannel.strideSize; int rotationOffset = p * rotationChannel.strideSize; vertices[offset + CPU_POSITION_OFFSET] = positionChannel.data[positionOffset + ParticleChannels.XOffset]; vertices[offset + CPU_POSITION_OFFSET + 1] = positionChannel.data[positionOffset + ParticleChannels.YOffset]; vertices[offset + CPU_POSITION_OFFSET + 2] = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; vertices[offset + CPU_COLOR_OFFSET] = colorChannel.data[colorOffset + ParticleChannels.RedOffset]; vertices[offset + CPU_COLOR_OFFSET + 1] = colorChannel.data[colorOffset + ParticleChannels.GreenOffset]; vertices[offset + CPU_COLOR_OFFSET + 2] = colorChannel.data[colorOffset + ParticleChannels.BlueOffset]; vertices[offset + CPU_COLOR_OFFSET + 3] = colorChannel.data[colorOffset + ParticleChannels.AlphaOffset]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET] = scaleChannel.data[p * scaleChannel.strideSize]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET + 1] = rotationChannel.data[rotationOffset + ParticleChannels.CosineOffset]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET + 2] = rotationChannel.data[rotationOffset + ParticleChannels.SineOffset]; vertices[offset + CPU_REGION_OFFSET] = regionChannel.data[regionOffset + ParticleChannels.UOffset]; vertices[offset + CPU_REGION_OFFSET + 1] = regionChannel.data[regionOffset + ParticleChannels.VOffset]; vertices[offset + CPU_REGION_OFFSET + 2] = regionChannel.data[regionOffset + ParticleChannels.U2Offset]; vertices[offset + CPU_REGION_OFFSET + 3] = regionChannel.data[regionOffset + ParticleChannels.V2Offset]; } } renderable.meshPart.size = bufferedParticlesCount; renderable.meshPart.mesh.setVertices(vertices, 0, bufferedParticlesCount * CPU_VERTEX_SIZE); renderable.meshPart.update(); }
/** Updates the bounding box using the position channel. */ protected void calculateBoundingBox () { boundingBox.clr(); FloatChannel positionChannel = particles.getChannel(ParticleChannels.Position); for(int pos = 0, c = positionChannel.strideSize*particles.size ; pos < c; pos += positionChannel.strideSize){ boundingBox.ext( positionChannel.data[pos + ParticleChannels.XOffset], positionChannel.data[pos + ParticleChannels.YOffset], positionChannel.data[pos + ParticleChannels.ZOffset]); } }
@Override protected void flush(int[] offsets){ int tp = 0; for(PointSpriteControllerRenderData data: renderData){ FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel = data.rotationChannel; for (int p = 0; p < data.controller.particles.size; ++p, ++tp) { int offset = offsets[tp]*CPU_VERTEX_SIZE; int regionOffset = p*regionChannel.strideSize; int positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize; int rotationOffset = p*rotationChannel.strideSize; vertices[offset + CPU_POSITION_OFFSET] = positionChannel.data[positionOffset + ParticleChannels.XOffset]; vertices[offset + CPU_POSITION_OFFSET+1] = positionChannel.data[positionOffset + ParticleChannels.YOffset]; vertices[offset + CPU_POSITION_OFFSET+2] = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; vertices[offset + CPU_COLOR_OFFSET] = colorChannel.data[colorOffset + ParticleChannels.RedOffset]; vertices[offset + CPU_COLOR_OFFSET+1] = colorChannel.data[colorOffset + ParticleChannels.GreenOffset]; vertices[offset + CPU_COLOR_OFFSET+2] = colorChannel.data[colorOffset + ParticleChannels.BlueOffset]; vertices[offset + CPU_COLOR_OFFSET+3] = colorChannel.data[colorOffset + ParticleChannels.AlphaOffset]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET] = scaleChannel.data[p* scaleChannel.strideSize]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET+1] = rotationChannel.data[rotationOffset + ParticleChannels.CosineOffset]; vertices[offset + CPU_SIZE_AND_ROTATION_OFFSET+2] = rotationChannel.data[rotationOffset + ParticleChannels.SineOffset]; vertices[offset + CPU_REGION_OFFSET] = regionChannel.data[regionOffset + ParticleChannels.UOffset]; vertices[offset + CPU_REGION_OFFSET+1] = regionChannel.data[regionOffset + ParticleChannels.VOffset]; vertices[offset + CPU_REGION_OFFSET+2] = regionChannel.data[regionOffset + ParticleChannels.U2Offset]; vertices[offset + CPU_REGION_OFFSET+3] = regionChannel.data[regionOffset + ParticleChannels.V2Offset]; } } renderable.meshPartSize = bufferedParticlesCount; renderable.mesh.setVertices(vertices, 0, bufferedParticlesCount*CPU_VERTEX_SIZE); }
@Override public void init (FloatChannel channel) { for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){ channel.data[i + ParticleChannels.UOffset] = 0; channel.data[i + ParticleChannels.VOffset] = 0; channel.data[i + ParticleChannels.U2Offset] = 1; channel.data[i + ParticleChannels.V2Offset] = 1; channel.data[i + ParticleChannels.HalfWidthOffset] = 0.5f; channel.data[i + ParticleChannels.HalfHeightOffset] = 0.5f; } }
@Override public void init (FloatChannel channel) { for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){ channel.data[i + ParticleChannels.CosineOffset] = 1; channel.data[i + ParticleChannels.SineOffset] = 0; } }
@Override public void init (FloatChannel channel) { for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){ channel.data[i + ParticleChannels.XOffset] = channel.data[i + ParticleChannels.YOffset] = channel.data[i + ParticleChannels.ZOffset] = 0; channel.data[i + ParticleChannels.WOffset] = 1; } }
private void fillVerticesGPU (int[] particlesOffset) { int tp=0; for(BillboardControllerRenderData data : renderData){ FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel = data.rotationChannel; for(int p=0, c = data.controller.particles.size; p < c; ++p, ++tp){ int baseOffset = particlesOffset[tp]*currentVertexSize*4; float scale = scaleChannel.data[p* scaleChannel.strideSize]; int regionOffset = p*regionChannel.strideSize; int positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize; int rotationOffset = p*rotationChannel.strideSize; float px = positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset + ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; float u = regionChannel.data[regionOffset +ParticleChannels.UOffset]; float v = regionChannel.data[regionOffset +ParticleChannels.VOffset]; float u2 = regionChannel.data[regionOffset +ParticleChannels.U2Offset]; float v2 = regionChannel.data[regionOffset +ParticleChannels.V2Offset]; float sx = regionChannel.data[regionOffset +ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset+ParticleChannels.HalfHeightOffset] * scale; float r = colorChannel.data[colorOffset +ParticleChannels.RedOffset]; float g = colorChannel.data[colorOffset +ParticleChannels.GreenOffset]; float b = colorChannel.data[colorOffset +ParticleChannels.BlueOffset]; float a = colorChannel.data[colorOffset +ParticleChannels.AlphaOffset]; float cosRotation = rotationChannel.data[rotationOffset +ParticleChannels.CosineOffset]; float sinRotation = rotationChannel.data[rotationOffset +ParticleChannels.SineOffset]; //bottom left, bottom right, top right, top left putVertex(vertices, baseOffset, px, py, pz, u, v2, -sx, -sy, cosRotation, sinRotation, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, px, py, pz, u2, v2, sx, -sy, cosRotation, sinRotation, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, px, py, pz, u2, v, sx, sy, cosRotation, sinRotation, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, px, py, pz, u, v, -sx, sy, cosRotation, sinRotation, r, g, b, a); baseOffset += currentVertexSize; } } }
private void fillVerticesToViewPointCPU (int[] particlesOffset) { int tp=0; for(BillboardControllerRenderData data : renderData){ FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel = data.rotationChannel; for(int p=0, c = data.controller.particles.size; p < c; ++p, ++tp){ int baseOffset = particlesOffset[tp]*currentVertexSize*4; float scale = scaleChannel.data[p* scaleChannel.strideSize]; int regionOffset = p*regionChannel.strideSize; int positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize; int rotationOffset = p*rotationChannel.strideSize; float px = positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset + ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; float u = regionChannel.data[regionOffset +ParticleChannels.UOffset]; float v = regionChannel.data[regionOffset +ParticleChannels.VOffset]; float u2 = regionChannel.data[regionOffset +ParticleChannels.U2Offset]; float v2 = regionChannel.data[regionOffset +ParticleChannels.V2Offset]; float sx = regionChannel.data[regionOffset +ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset+ParticleChannels.HalfHeightOffset] * scale; float r = colorChannel.data[colorOffset +ParticleChannels.RedOffset]; float g = colorChannel.data[colorOffset +ParticleChannels.GreenOffset]; float b = colorChannel.data[colorOffset +ParticleChannels.BlueOffset]; float a = colorChannel.data[colorOffset +ParticleChannels.AlphaOffset]; float cosRotation = rotationChannel.data[rotationOffset +ParticleChannels.CosineOffset]; float sinRotation = rotationChannel.data[rotationOffset +ParticleChannels.SineOffset]; Vector3 look = TMP_V3.set(camera.position).sub(px, py, pz).nor(), //normal right = TMP_V1.set(camera.up).crs(look).nor(), //tangent up = TMP_V2.set(look).crs(right); right.scl(sx); up.scl(sy); if(cosRotation != 1){ TMP_M3.setToRotation(look, cosRotation, sinRotation); putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x-TMP_V2.x, -TMP_V1.y-TMP_V2.y, -TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x-TMP_V2.x, TMP_V1.y-TMP_V2.y, TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x+TMP_V2.x, TMP_V1.y+TMP_V2.y, TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x, -TMP_V1.y+TMP_V2.y, -TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v, r, g, b, a); } else { putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x-TMP_V2.x+px, -TMP_V1.y-TMP_V2.y+py, -TMP_V1.z-TMP_V2.z+pz), u, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x-TMP_V2.x+px, TMP_V1.y-TMP_V2.y+py, TMP_V1.z-TMP_V2.z+pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x+TMP_V2.x+px, TMP_V1.y+TMP_V2.y+py, TMP_V1.z+TMP_V2.z+pz), u2, v, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x+px, -TMP_V1.y+TMP_V2.y+py, -TMP_V1.z+TMP_V2.z+pz), u, v, r, g, b, a); } } } }
private void fillVerticesToScreenCPU (int[] particlesOffset) { Vector3 look = TMP_V3.set(camera.direction).scl(-1), //normal right = TMP_V4.set(camera.up).crs(look).nor(), //tangent up = camera.up; int tp=0; for(BillboardControllerRenderData data : renderData){ FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel = data.rotationChannel; for(int p=0, c = data.controller.particles.size; p < c; ++p, ++tp){ int baseOffset = particlesOffset[tp]*currentVertexSize*4; float scale = scaleChannel.data[p* scaleChannel.strideSize]; int regionOffset = p*regionChannel.strideSize; int positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize; int rotationOffset = p*rotationChannel.strideSize; float px = positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset + ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; float u = regionChannel.data[regionOffset +ParticleChannels.UOffset]; float v = regionChannel.data[regionOffset +ParticleChannels.VOffset]; float u2 = regionChannel.data[regionOffset +ParticleChannels.U2Offset]; float v2 = regionChannel.data[regionOffset +ParticleChannels.V2Offset]; float sx = regionChannel.data[regionOffset +ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset+ParticleChannels.HalfHeightOffset] * scale; float r = colorChannel.data[colorOffset +ParticleChannels.RedOffset]; float g = colorChannel.data[colorOffset +ParticleChannels.GreenOffset]; float b = colorChannel.data[colorOffset +ParticleChannels.BlueOffset]; float a = colorChannel.data[colorOffset +ParticleChannels.AlphaOffset]; float cosRotation = rotationChannel.data[rotationOffset +ParticleChannels.CosineOffset]; float sinRotation = rotationChannel.data[rotationOffset +ParticleChannels.SineOffset]; TMP_V1.set(right).scl(sx); TMP_V2.set(up).scl(sy); if(cosRotation != 1){ TMP_M3.setToRotation(look, cosRotation, sinRotation); putVertex( vertices, baseOffset, TMP_V6.set(-TMP_V1.x-TMP_V2.x, -TMP_V1.y-TMP_V2.y, -TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x-TMP_V2.x, TMP_V1.y-TMP_V2.y, TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x+TMP_V2.x, TMP_V1.y+TMP_V2.y, TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x, -TMP_V1.y+TMP_V2.y, -TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v, r, g, b, a); } else { putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x-TMP_V2.x+px, -TMP_V1.y-TMP_V2.y+py, -TMP_V1.z-TMP_V2.z+pz), u, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x-TMP_V2.x+px, TMP_V1.y-TMP_V2.y+py, TMP_V1.z-TMP_V2.z+pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x+TMP_V2.x+px, TMP_V1.y+TMP_V2.y+py, TMP_V1.z+TMP_V2.z+pz), u2, v, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x+px, -TMP_V1.y+TMP_V2.y+py, -TMP_V1.z+TMP_V2.z+pz), u, v, r, g, b, a); } } } }
@Override public void init (FloatChannel channel) { Arrays.fill(channel.data, 0, channel.data.length, 1); }