/* Copyright (c) 2012 Jesper Öqvist <jesper@llbit.se> * * 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 <http://www.gnu.org/licenses/>. */ package se.llbit.chunky.model; import se.llbit.chunky.resources.Texture; import se.llbit.chunky.world.BlockData; import se.llbit.math.DoubleSidedQuad; import se.llbit.math.Quad; import se.llbit.math.QuickMath; import se.llbit.math.Ray; import se.llbit.math.Transform; import se.llbit.math.Vector3; import se.llbit.math.Vector4; /** * Renders the Cocoa Plant * * @author Jesper Öqvist <jesper@llbit.se> */ public class CocoaPlantModel { private static final Quad[] large = { // front new Quad(new Vector3(12 / 16., 3 / 16., 7 / 16.), new Vector3(4 / 16., 3 / 16., 7 / 16.), new Vector3(12 / 16., 12 / 16., 7 / 16.), new Vector4(7 / 16., 15 / 16., 3 / 16., 12 / 16.)), // back new Quad(new Vector3(4 / 16., 3 / 16., 15 / 16.), new Vector3(12 / 16., 3 / 16., 15 / 16.), new Vector3(4 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 7 / 16., 3 / 16., 12 / 16.)), // left new Quad(new Vector3(4 / 16., 3 / 16., 7 / 16.), new Vector3(4 / 16., 3 / 16., 15 / 16.), new Vector3(4 / 16., 12 / 16., 7 / 16.), new Vector4(7 / 16., 15 / 16., 3 / 16., 12 / 16.)), // right new Quad(new Vector3(12 / 16., 3 / 16., 15 / 16.), new Vector3(12 / 16., 3 / 16., 7 / 16.), new Vector3(12 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 7 / 16., 3 / 16., 12 / 16.)), // top new Quad(new Vector3(12 / 16., 12 / 16., 7 / 16.), new Vector3(4 / 16., 12 / 16., 7 / 16.), new Vector3(12 / 16., 12 / 16., 15 / 16.), new Vector4(7 / 16., 0, 9 / 16., 1)), // bottom new Quad(new Vector3(4 / 16., 3 / 16., 7 / 16.), new Vector3(12 / 16., 3 / 16., 7 / 16.), new Vector3(4 / 16., 3 / 16., 15 / 16.), new Vector4(0, 7 / 16., 9 / 16., 1)),}; private static final Quad[] medium = { // front new Quad(new Vector3(11 / 16., 5 / 16., 9 / 16.), new Vector3(5 / 16., 5 / 16., 9 / 16.), new Vector3(11 / 16., 12 / 16., 9 / 16.), new Vector4(9 / 16., 15 / 16., 5 / 16., 12 / 16.)), // back new Quad(new Vector3(5 / 16., 5 / 16., 15 / 16.), new Vector3(11 / 16., 5 / 16., 15 / 16.), new Vector3(5 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 9 / 16., 5 / 16., 12 / 16.)), // left new Quad(new Vector3(5 / 16., 5 / 16., 9 / 16.), new Vector3(5 / 16., 5 / 16., 15 / 16.), new Vector3(5 / 16., 12 / 16., 9 / 16.), new Vector4(9 / 16., 15 / 16., 5 / 16., 12 / 16.)), // right new Quad(new Vector3(11 / 16., 5 / 16., 15 / 16.), new Vector3(11 / 16., 5 / 16., 9 / 16.), new Vector3(11 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 9 / 16., 5 / 16., 12 / 16.)), // top new Quad(new Vector3(11 / 16., 12 / 16., 9 / 16.), new Vector3(5 / 16., 12 / 16., 9 / 16.), new Vector3(11 / 16., 12 / 16., 15 / 16.), new Vector4(6 / 16., 0, 10 / 16., 1)), // bottom new Quad(new Vector3(5 / 16., 5 / 16., 9 / 16.), new Vector3(11 / 16., 5 / 16., 9 / 16.), new Vector3(5 / 16., 5 / 16., 15 / 16.), new Vector4(0, 6 / 16., 10 / 16., 1)),}; private static final Quad[] small = { // front new Quad(new Vector3(10 / 16., 7 / 16., 11 / 16.), new Vector3(6 / 16., 7 / 16., 11 / 16.), new Vector3(10 / 16., 12 / 16., 11 / 16.), new Vector4(11 / 16., 15 / 16., 7 / 16., 12 / 16.)), // back new Quad(new Vector3(6 / 16., 7 / 16., 15 / 16.), new Vector3(10 / 16., 7 / 16., 15 / 16.), new Vector3(6 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 11 / 16., 7 / 16., 12 / 16.)), // left new Quad(new Vector3(6 / 16., 7 / 16., 11 / 16.), new Vector3(6 / 16., 7 / 16., 15 / 16.), new Vector3(6 / 16., 12 / 16., 11 / 16.), new Vector4(11 / 16., 15 / 16., 7 / 16., 12 / 16.)), // right new Quad(new Vector3(10 / 16., 7 / 16., 15 / 16.), new Vector3(10 / 16., 7 / 16., 11 / 16.), new Vector3(10 / 16., 12 / 16., 15 / 16.), new Vector4(15 / 16., 11 / 16., 7 / 16., 12 / 16.)), // top new Quad(new Vector3(10 / 16., 12 / 16., 11 / 16.), new Vector3(6 / 16., 12 / 16., 11 / 16.), new Vector3(10 / 16., 12 / 16., 15 / 16.), new Vector4(4 / 16., 0, 12 / 16., 1)), // bottom new Quad(new Vector3(6 / 16., 7 / 16., 11 / 16.), new Vector3(10 / 16., 7 / 16., 11 / 16.), new Vector3(6 / 16., 7 / 16., 15 / 16.), new Vector4(0, 4 / 16., 12 / 16., 1)),}; private static final Quad stemNorth = new DoubleSidedQuad(new Vector3(.5, 12 / 16., .5), new Vector3(.5, 12 / 16., 1), new Vector3(.5, 1, .5), new Vector4(.5, 1, 12 / 16., 1)); private static final Quad[][][] fruit = new Quad[3][4][]; private static final Quad[] stem = new Quad[4]; static { fruit[0][0] = small; fruit[1][0] = medium; fruit[2][0] = large; stem[0] = stemNorth; for (int i = 1; i < 4; ++i) { stem[i] = stem[i - 1].transform(Transform.NONE.rotateY()); fruit[0][i] = Model.rotateY(fruit[0][i - 1]); fruit[1][i] = Model.rotateY(fruit[1][i - 1]); fruit[2][i] = Model.rotateY(fruit[2][i - 1]); } } private static final Texture[] tex = {Texture.cocoaPlantSmall, Texture.cocoaPlantMedium, Texture.cocoaPlantLarge}; public static boolean intersect(Ray ray) { int data = 0xF & (ray.getCurrentData() >> BlockData.OFFSET); int size = data >> 2; int direction = 3 & data; boolean hit = false; ray.t = Double.POSITIVE_INFINITY; for (Quad quad : fruit[size][direction]) { if (quad.intersect(ray)) { tex[size].getColor(ray); ray.color.w = 1; ray.t = ray.tNext; ray.n.set(quad.n); hit = true; } } if (stem[direction].intersect(ray)) { float[] color = tex[size].getColor(ray.u, ray.v); if (color[3] > Ray.EPSILON) { ray.color.set(color); ray.t = ray.tNext; ray.n.set(stem[direction].n); ray.n.scale(QuickMath.signum(-ray.d.dot(stem[direction].n))); hit = true; } } if (hit) { ray.distance += ray.t; ray.o.scaleAdd(ray.t, ray.d); } return hit; } }