All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.llbit.chunky.model.RedstoneWireModel Maven / Gradle / Ivy

There is a newer version: 1.4.5
Show newest version
/* Copyright (c) 2012 Jesper Öqvist 
 *
 * This file is part of Chunky.
 *
 * Chunky is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Chunky is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with Chunky.  If not, see .
 */
package se.llbit.chunky.model;

import se.llbit.chunky.resources.Texture;
import se.llbit.chunky.world.BlockData;
import se.llbit.math.ColorUtil;
import se.llbit.math.Quad;
import se.llbit.math.Ray;
import se.llbit.math.Vector3;
import se.llbit.math.Vector4;

public class RedstoneWireModel {
  private static final Quad[] quads = {
      // 0000 no connection
      new Quad(new Vector3(11 / 16., 0, 5 / 16.), new Vector3(5 / 16., 0, 5 / 16.),
          new Vector3(11 / 16., 0, 11 / 16.), new Vector4(11 / 16., 5 / 16., 11 / 16., 5 / 16.)),

      // 0001 east
      new Quad(new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(1, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 0010 west
      new Quad(new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(1, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 0011 east west
      new Quad(new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(1, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 0100 north
      new Quad(new Vector3(1, 0, 1), new Vector3(1, 0, 0), new Vector3(0, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 0101 north east
      new Quad(new Vector3(1, 0, 0), new Vector3(5 / 16., 0, 0), new Vector3(1, 0, 11 / 16.),
          new Vector4(1, 5 / 16., 1, 5 / 16.)),

      // 0110 north west
      new Quad(new Vector3(11 / 16., 0, 0), new Vector3(0, 0, 0),
          new Vector3(11 / 16., 0, 11 / 16.), new Vector4(11 / 16., 0, 1, 5 / 16.)),

      // 0111 north east west
      new Quad(new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(1, 0, 11 / 16.),
          new Vector4(1, 0 / 16., 1, 5 / 16.)),

      // 1000 south
      new Quad(new Vector3(1, 0, 1), new Vector3(1, 0, 0), new Vector3(0, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 1001 south east
      new Quad(new Vector3(1, 0, 5 / 16.), new Vector3(5 / 16., 0, 5 / 16.),
          new Vector3(1, 0, 1), new Vector4(1, 5 / 16., 11 / 16., 0)),

      // 1010 south west
      new Quad(new Vector3(11 / 16., 0, 5 / 16.), new Vector3(0, 0, 5 / 16.),
          new Vector3(11 / 16., 0, 1), new Vector4(11 / 16., 0, 11 / 16., 0)),

      // 1011 south east west
      new Quad(new Vector3(16 / 16., 0, 5 / 16.), new Vector3(0 / 16., 0, 5 / 16.),
          new Vector3(16 / 16., 0, 1), new Vector4(16 / 16., 0 / 16., 11 / 16., 0)),

      // 1100 north south
      new Quad(new Vector3(1, 0, 1), new Vector3(1, 0, 0), new Vector3(0, 0, 1),
          new Vector4(1, 0, 1, 0)),

      // 1101 north south east
      new Quad(new Vector3(1, 0, 0), new Vector3(5 / 16., 0, 0), new Vector3(1, 0, 1),
          new Vector4(1, 5 / 16., 1, 0)),

      // 1110 north south west
      new Quad(new Vector3(11 / 16., 0, 0), new Vector3(0, 0, 0), new Vector3(11 / 16., 0, 1),
          new Vector4(11 / 16., 0, 1, 0)),

      // 1111 north south east west
      new Quad(new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(1, 0, 1),
          new Vector4(1, 0, 1, 0)),};

  private static final Quad eastSide =
      new Quad(new Vector3(1, 1, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 1),
          new Vector4(1, 0, 1, 0));
  private static final Quad westSide =
      new Quad(new Vector3(0, 1, 1), new Vector3(0, 0, 1), new Vector3(0, 1, 0),
          new Vector4(1, 0, 1, 0));
  private static final Quad northSide =
      new Quad(new Vector3(0, 1, 0), new Vector3(0, 0, 0), new Vector3(1, 1, 0),
          new Vector4(1, 0, 1, 0));
  private static final Quad southSide =
      new Quad(new Vector3(1, 1, 1), new Vector3(1, 0, 1), new Vector3(0, 1, 1),
          new Vector4(1, 0, 1, 0));

  private static final Texture[] tex =
      {Texture.redstoneWireCross, Texture.redstoneWire, Texture.redstoneWire, Texture.redstoneWire,
          Texture.redstoneWire, Texture.redstoneWireCross, Texture.redstoneWireCross,
          Texture.redstoneWireCross, Texture.redstoneWire, Texture.redstoneWireCross,
          Texture.redstoneWireCross, Texture.redstoneWireCross, Texture.redstoneWire,
          Texture.redstoneWireCross, Texture.redstoneWireCross, Texture.redstoneWireCross,};

  private static final float[][] wireColor = new float[16][3];

  static {
    float[] color0 = new float[3];
    float[] color1 = new float[3];
    ColorUtil.getRGBComponents(0x4D0000, color0);
    ColorUtil.toLinear(color0);
    ColorUtil.getRGBComponents(0xFD3100, color1);
    ColorUtil.toLinear(color1);
    for (int i = 0; i < 16; ++i) {
      wireColor[i][0] = color0[0] + (i / 15.f) * (color1[0] - color0[0]);
      wireColor[i][1] = color0[1] + (i / 15.f) * (color1[1] - color0[1]);
      wireColor[i][2] = color0[2] + (i / 15.f) * (color1[2] - color0[2]);
    }
  }

  public static boolean intersect(Ray ray) {
    int data = ray.getCurrentData();
    boolean hit = false;
    int power = ray.getBlockData();
    int connection = 0xF & (data >> BlockData.RSW_EAST_CONNECTION);
    ray.t = Double.POSITIVE_INFINITY;
    Quad quad = quads[connection];
    if (quad.intersect(ray)) {
      float[] color = tex[connection].getColor(ray.u, ray.v);
      if (color[3] > Ray.EPSILON) {
        ray.color.x = color[0] * wireColor[power][0];
        ray.color.y = color[1] * wireColor[power][1];
        ray.color.z = color[2] * wireColor[power][2];
        ray.color.w = color[3];
        ray.n.set(quad.n);
        ray.t = ray.tNext;
        hit = true;
      }
    }
    if ((data & (1 << BlockData.RSW_EAST_SIDE)) != 0) {
      if (eastSide.intersect(ray)) {
        float[] color = Texture.redstoneWire.getColor(ray.u, ray.v);
        if (color[3] > Ray.EPSILON) {
          ray.color.x = color[0] * wireColor[power][0];
          ray.color.y = color[1] * wireColor[power][1];
          ray.color.z = color[2] * wireColor[power][2];
          ray.color.w = color[3];
          ray.n.set(eastSide.n);
          ray.t = ray.tNext;
          hit = true;
        }
      }
    }
    if ((data & (1 << BlockData.RSW_WEST_SIDE)) != 0) {
      if (westSide.intersect(ray)) {
        float[] color = Texture.redstoneWire.getColor(ray.u, ray.v);
        if (color[3] > Ray.EPSILON) {
          ray.color.x = color[0] * wireColor[power][0];
          ray.color.y = color[1] * wireColor[power][1];
          ray.color.z = color[2] * wireColor[power][2];
          ray.color.w = color[3];
          ray.n.set(westSide.n);
          ray.t = ray.tNext;
          hit = true;
        }
      }
    }
    if ((data & (1 << BlockData.RSW_NORTH_SIDE)) != 0) {
      if (northSide.intersect(ray)) {
        float[] color = Texture.redstoneWire.getColor(ray.u, ray.v);
        if (color[3] > Ray.EPSILON) {
          ray.color.x = color[0] * wireColor[power][0];
          ray.color.y = color[1] * wireColor[power][1];
          ray.color.z = color[2] * wireColor[power][2];
          ray.color.w = color[3];
          ray.n.set(northSide.n);
          ray.t = ray.tNext;
          hit = true;
        }
      }
    }
    if ((data & (1 << BlockData.RSW_SOUTH_SIDE)) != 0) {
      if (southSide.intersect(ray)) {
        float[] color = Texture.redstoneWire.getColor(ray.u, ray.v);
        if (color[3] > Ray.EPSILON) {
          ray.color.x = color[0] * wireColor[power][0];
          ray.color.y = color[1] * wireColor[power][1];
          ray.color.z = color[2] * wireColor[power][2];
          ray.color.w = color[3];
          ray.n.set(southSide.n);
          ray.t = ray.tNext;
          hit = true;
        }
      }
    }
    if (hit) {
      ray.distance += ray.tNext;
      ray.o.scaleAdd(ray.tNext, ray.d);
      return true;
    }
    return false;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy