Hi, i created a control to change/morph the color of its parent spatial, I thought I should share it to get some feedback if I am doing things totally wrong and maybe someone else finds it useful. So criticism would be appreciated
[java]
Spatial cube = newCube(ColorRGBA.Red);
cube.addControl(new C_ColorChanger(ColorRGBA.Green) {
private float percent = 0;
private final float MAX = 5;
@Override
public void update(float tpf) {
percent += tpf * 100 / MAX;
Log.d(LOG_TAG, "percent=" + percent);
setPercent(percent);
super.update(tpf);
}
});
rootNode.attachChild(cube);
/**
-
adjusts the color from the target spatial and morphs it to the endColor. Use
-
{@link C_ColorChanger#setPercent(float)} to update the color
*/
public class C_ColorChanger extends AbstractControl {private static final String LOG_TAG = âC_ColorChangerâ;
private ColorRGBA objectColor;
private ColorRGBA startColor;
private ColorRGBA endColor;
private int percent = 0;
private int lastPercent;
private Spatial lastSpatial;
private Geometry myGeometry;public C_ColorChanger(ColorRGBA endColor) {
this.endColor = endColor.clone();
}/**
- @param startColor
-
can be null, then the initial color of the object will be used
-
as the start color
-
@param endColor
*/
public C_ColorChanger(ColorRGBA startColor, ColorRGBA endColor) {
if (startColor != null) {
this.startColor = startColor.clone();
}
this.endColor = endColor.clone();
}
@Override
protected void controlUpdate(float tpf) {
if (percent != lastPercent) {
lastPercent = percent;
if (lastSpatial != getSpatial()) {
lastSpatial = getSpatial();
myGeometry = findOutestGeometryFor(lastSpatial);
Log.d(LOG_TAG, âfound myGeometry=â + myGeometry
+ " for spatial=" + lastSpatial);
}
if (objectColor == null) {
objectColor = getfrom(myGeometry);
if (startColor == null) {
startColor = objectColor.clone();
}
}
// then change the found color object
objectColor.interpolate(startColor, endColor, percent / 100f);
}
}public void setEndColor(ColorRGBA endColor) {
this.endColor = endColor;
}/**
- Changes the color directly to the passed value. The passed color will
- then also be the new end color. If you only want to change the endColor
- to a new value without applying it directly use
- {@link C_ColorChanger#setEndColor(ColorRGBA)}
-
@param color
*/
public void setColor(ColorRGBA color) {
setEndColor(color);
setPercent(100);
}
private ColorRGBA getfrom(Geometry g) {
MatParam c;
c = myGeometry.getMaterial().getParam(âAmbientâ);
if (c != null) {
return (ColorRGBA) c.getValue();
}
c = myGeometry.getMaterial().getParam(âDiffuseâ);
if (c != null) {
return (ColorRGBA) c.getValue();
}
c = myGeometry.getMaterial().getParam(âSpecularâ);
if (c != null) {
return (ColorRGBA) c.getValue();
}
Log.w(LOG_TAG, âFound no color attribute in geometry=â + g);
return null;
}private Geometry findOutestGeometryFor(Spatial s) {
if (s instanceof Geometry) {
return (Geometry) s;
} else {
List<Spatial> c = ((Node) s).getChildren();
for (int i = 0; i < c.size(); i++) {
Geometry g = findOutestGeometryFor(c.get(i));
if (g != null) {
return g;
}
}
return null;
}
}/**
- @param percent
-
a value between 0 and 100
*/
public void setPercent(float percent) {
if (percent > 100) {
percent = 100;
} else if (percent < 0) {
percent = 0;
}
this.percent = (int) percent;
}@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
}
[/java]