Files
CodeChickenCore/codechicken/lib/lighting/LightModel.java
T

106 lines
3.2 KiB
Java
Raw Normal View History

2013-07-16 17:58:02 +10:00
package codechicken.lib.lighting;
import codechicken.lib.render.CCRenderState;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Vector3;
2014-04-07 14:02:47 +10:00
public class LightModel implements CCRenderState.IVertexOperation
2013-07-16 17:58:02 +10:00
{
2014-04-07 14:02:47 +10:00
public static final int operationIndex = CCRenderState.registerOperation();
2013-07-16 17:58:02 +10:00
public static class Light
{
public Vector3 ambient = new Vector3();
public Vector3 diffuse = new Vector3();
public Vector3 position;
2014-04-07 14:02:47 +10:00
public Light(Vector3 pos) {
2013-07-16 17:58:02 +10:00
position = pos.copy().normalize();
}
2014-04-07 14:02:47 +10:00
public Light setDiffuse(Vector3 vec) {
2013-07-16 17:58:02 +10:00
diffuse.set(vec);
return this;
}
2014-04-07 14:02:47 +10:00
public Light setAmbient(Vector3 vec) {
2013-07-16 17:58:02 +10:00
ambient.set(vec);
return this;
}
}
public static LightModel standardLightModel;
2014-04-07 14:02:47 +10:00
static {
2013-07-16 17:58:02 +10:00
standardLightModel = new LightModel()
.setAmbient(new Vector3(0.4, 0.4, 0.4))
.addLight(new Light(new Vector3(0.2, 1, -0.7))
2014-04-07 14:02:47 +10:00
.setDiffuse(new Vector3(0.6, 0.6, 0.6)))
2013-07-16 17:58:02 +10:00
.addLight(new Light(new Vector3(-0.2, 1, 0.7))
2014-04-07 14:02:47 +10:00
.setDiffuse(new Vector3(0.6, 0.6, 0.6)));
2013-07-16 17:58:02 +10:00
}
private Vector3 ambient = new Vector3();
private Light[] lights = new Light[8];
private int lightCount;
2014-04-07 14:02:47 +10:00
public LightModel addLight(Light light) {
2013-07-16 17:58:02 +10:00
lights[lightCount++] = light;
return this;
}
2014-04-07 14:02:47 +10:00
public LightModel setAmbient(Vector3 vec) {
2013-07-16 17:58:02 +10:00
ambient.set(vec);
return this;
}
/**
* @param colour The pre-lighting vertex colour. RGBA format
* @param normal The normal at the vertex
* @return The lighting applied colour
*/
2014-04-07 14:02:47 +10:00
public int apply(int colour, Vector3 normal) {
2013-07-16 17:58:02 +10:00
Vector3 n_colour = ambient.copy();
2014-04-07 14:02:47 +10:00
for (int l = 0; l < lightCount; l++) {
2013-07-16 17:58:02 +10:00
Light light = lights[l];
double n_l = light.position.dotProduct(normal);
double f = n_l > 0 ? 1 : 0;
2014-04-07 14:02:47 +10:00
n_colour.x += light.ambient.x + f * light.diffuse.x * n_l;
n_colour.y += light.ambient.y + f * light.diffuse.y * n_l;
n_colour.z += light.ambient.z + f * light.diffuse.z * n_l;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
if (n_colour.x > 1)
2013-07-16 17:58:02 +10:00
n_colour.x = 1;
2014-04-07 14:02:47 +10:00
if (n_colour.y > 1)
2013-07-16 17:58:02 +10:00
n_colour.y = 1;
2014-04-07 14:02:47 +10:00
if (n_colour.z > 1)
2013-07-16 17:58:02 +10:00
n_colour.z = 1;
2014-04-07 14:02:47 +10:00
n_colour.multiply((colour >>> 24) / 255D, (colour >> 16 & 0xFF) / 255D, (colour >> 8 & 0xFF) / 255D);
return (int) (n_colour.x * 255) << 24 | (int) (n_colour.y * 255) << 16 | (int) (n_colour.z * 255) << 8 | colour & 0xFF;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
@Override
2014-04-07 14:02:47 +10:00
public boolean load() {
CCRenderState.pipeline.addDependency(CCRenderState.normalAttrib);
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
return true;
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
2013-07-16 17:58:02 +10:00
@Override
2014-04-07 14:02:47 +10:00
public void operate() {
CCRenderState.setColour(apply(CCRenderState.colour, CCRenderState.normal));
2013-07-16 17:58:02 +10:00
}
2014-04-07 14:02:47 +10:00
@Override
public int operationID() {
return operationIndex;
}
public PlanarLightModel reducePlanar() {
2013-07-16 17:58:02 +10:00
int[] colours = new int[6];
2014-04-07 14:02:47 +10:00
for (int i = 0; i < 6; i++)
2013-07-16 17:58:02 +10:00
colours[i] = apply(-1, Rotation.axes[i]);
return new PlanarLightModel(colours);
}
}