/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.graphics.g3d.particles.renderers;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.particles.ParticleChannels;
import com.badlogic.gdx.graphics.g3d.particles.ParticleControllerComponent;
import com.badlogic.gdx.graphics.g3d.particles.batches.BillboardParticleBatch;
import com.badlogic.gdx.graphics.g3d.particles.batches.ModelInstanceParticleBatch;
import com.badlogic.gdx.graphics.g3d.particles.batches.ParticleBatch;
/** A {@link ParticleControllerRenderer} which will render particles as {@link ModelInstance} to a
* {@link ModelInstanceParticleBatch}.
* @author Inferno */
public class ModelInstanceRenderer extends
ParticleControllerRenderer<ModelInstanceControllerRenderData, ModelInstanceParticleBatch> {
private boolean hasColor, hasScale, hasRotation;
public ModelInstanceRenderer () {
super(new ModelInstanceControllerRenderData());
}
public ModelInstanceRenderer (ModelInstanceParticleBatch batch) {
this();
setBatch(batch);
}
@Override
public void allocateChannels () {
renderData.positionChannel = controller.particles.addChannel(ParticleChannels.Position);
}
@Override
public void init () {
renderData.modelInstanceChannel = controller.particles.getChannel(ParticleChannels.ModelInstance);
renderData.colorChannel = controller.particles.getChannel(ParticleChannels.Color);
renderData.scaleChannel = controller.particles.getChannel(ParticleChannels.Scale);
renderData.rotationChannel = controller.particles.getChannel(ParticleChannels.Rotation3D);
hasColor = renderData.colorChannel != null;
hasScale = renderData.scaleChannel != null;
hasRotation = renderData.rotationChannel != null;
}
@Override
public void update () {
for (int i = 0, positionOffset = 0, c = controller.particles.size; i < c; ++i, positionOffset += renderData.positionChannel.strideSize) {
ModelInstance instance = renderData.modelInstanceChannel.data[i];
float scale = hasScale ? renderData.scaleChannel.data[i] : 1;
float qx = 0, qy = 0, qz = 0, qw = 1;
if (hasRotation) {
int rotationOffset = i * renderData.rotationChannel.strideSize;
qx = renderData.rotationChannel.data[rotationOffset + ParticleChannels.XOffset];
qy = renderData.rotationChannel.data[rotationOffset + ParticleChannels.YOffset];
qz = renderData.rotationChannel.data[rotationOffset + ParticleChannels.ZOffset];
qw = renderData.rotationChannel.data[rotationOffset + ParticleChannels.WOffset];
}
instance.transform.set(renderData.positionChannel.data[positionOffset + ParticleChannels.XOffset],
renderData.positionChannel.data[positionOffset + ParticleChannels.YOffset],
renderData.positionChannel.data[positionOffset + ParticleChannels.ZOffset], qx, qy, qz, qw, scale, scale, scale);
if (hasColor) {
int colorOffset = i * renderData.colorChannel.strideSize;
ColorAttribute colorAttribute = (ColorAttribute)instance.materials.get(0).get(ColorAttribute.Diffuse);
BlendingAttribute blendingAttribute = (BlendingAttribute)instance.materials.get(0).get(BlendingAttribute.Type);
colorAttribute.color.r = renderData.colorChannel.data[colorOffset + ParticleChannels.RedOffset];
colorAttribute.color.g = renderData.colorChannel.data[colorOffset + ParticleChannels.GreenOffset];
colorAttribute.color.b = renderData.colorChannel.data[colorOffset + ParticleChannels.BlueOffset];
if (blendingAttribute != null)
blendingAttribute.opacity = renderData.colorChannel.data[colorOffset + ParticleChannels.AlphaOffset];
}
}
super.update();
}
@Override
public ParticleControllerComponent copy () {
return new ModelInstanceRenderer(batch);
}
@Override
public boolean isCompatible (ParticleBatch<?> batch) {
return batch instanceof ModelInstanceParticleBatch;
}
}