public static TexturedPolygon newTexturedPolygon(Texture texture, Vector... vectors) { TexturedPolygon texturedPolygon = TexturedPolygonImpl.newInstance(texture, vectors); if (vectors.length >= 2) { if (texture instanceof ShadedTexture) { ShadedTexture shadedTexture = ShadedTexture.class.cast(texture); List<PointLight> pointLights = new ArrayList<>(); Vector normal = texturedPolygon.getNormal(); Vector location = null; double x = normal.getX(); double y = normal.getY() + 500.0D; double z = normal.getZ(); double distanceFalloff = 2500.0D; Color intensity = Color.white(); location = Vector.newInstance(x, y, z); PointLight pointLight = PointLight.newInstance(); pointLight.setLocation(location); pointLight.setIntensity(intensity); pointLight.setDistanceFalloff(distanceFalloff); pointLights.add(pointLight); Color ambientLightIntensity = Color.valueOf(0xFF333333); ShadedSurfaceTexture.createShadedSurfaceTexture( texturedPolygon, shadedTexture, pointLights, new ArrayList<Polygon>(), ambientLightIntensity); } else { Vector origin = vectors[0]; Vector v = vectors[1].copy(); Vector normal = texturedPolygon.getNormal(); v.subtract(origin); Vector u = Vector.toCrossProduct(normal, v); BoundingBox boundingBox = texturedPolygon.getTextureBounds(); boundingBox.setOrigin(origin); boundingBox.setU(u); boundingBox.setV(v); } } return texturedPolygon; }
private double doGetIntersectionForTriangle(Ray ray, Vector a, Vector b, Vector c) { Vector direction = ray.getDirection(); Vector edge1 = Vector.copyAndSubtract(b, a); Vector edge2 = Vector.copyAndSubtract(c, a); Vector p = Vector.toCrossProduct(direction, edge2); double determinant = edge1.getDotProduct(p); if (determinant == 0.0D) { return -1.0D; } double inverseDeterminant = 1.0D / determinant; Vector origin = Vector.newInstance(ray.getOrigin()); Vector vector = Vector.copyAndSubtract(origin, a); double u = vector.getDotProduct(p) * inverseDeterminant; if (u < 0.0D || u > 1.0D) { return -1.0D; } Vector q = Vector.toCrossProduct(vector, edge1); double v = direction.getDotProduct(q) * inverseDeterminant; if (v < 0.0D || u + v > 1.0D) { return -1.0D; } double t = edge2.getDotProduct(q) * inverseDeterminant; if (t > EPSILON) { return t; } else { return -1.0D; } }
public static Transform lookAt(final Point source, final Point target, final Vector up) { final double[][] m = new double[4][4]; m[0][3] = source.getX(); m[1][3] = source.getY(); m[2][3] = source.getZ(); m[3][3] = 1.0D; final Vector direction = Vector.copyAndSubtract(target, source).normalize(); final Vector vector0 = Vector.copyAndNormalize(up); final Vector vector1 = Vector.toCrossProduct(vector0, direction); if (vector1.length() == 0.0D) { return newInstance(); } final Vector vector2 = vector1.normalize(); final Vector vector3 = Vector.toCrossProduct(direction, vector2); m[0][0] = vector2.getX(); m[1][0] = vector2.getY(); m[2][0] = vector2.getZ(); m[3][0] = 0.0D; m[0][1] = vector3.getX(); m[1][1] = vector3.getY(); m[2][1] = vector3.getZ(); m[3][1] = 0.0D; m[0][2] = direction.getX(); m[1][2] = direction.getY(); m[2][2] = direction.getZ(); m[3][2] = 0.0D; final Matrix matrix = Matrix.newInstance(m); return newInstance(matrix.inverse(), matrix); }
@Override public final Vector getNormal() { if (normal != null) { return normal; } else if (vectors.size() < 3) { return null; } else { Vector vector1 = vectors.get(0).copy(); Vector vector2 = vectors.get(1); Vector vector3 = vectors.get(2).copy(); Vector vector4; vector1.subtract(vector2); vector3.subtract(vector2); vector4 = Vector.toCrossProduct(vector3, vector1); vector4.normalize(); return vector4; } }
@Override public final BoundingBox getBounds() { BoundingBox boundingBox = BoundingBox.newInstance(); double minimum = Double.MAX_VALUE; Vector u = Vector.newInstance(0.0D, 0.0D, 0.0D); Vector v; Vector d = Vector.newInstance(0.0D, 0.0D, 0.0D); int size = vectors.size(); for (int i = 0; i < size; i++) { Vector vector1 = vectors.get((i + 1) % size); Vector vector2 = vectors.get(i); u.set(vector1); u.subtract(vector2); u.normalize(); v = Vector.toCrossProduct(getNormal(), u); v.normalize(); double uMaximum = 0.0D; double uMinimum = 0.0D; double vMaximum = 0.0D; double vMinimum = 0.0D; for (int j = 0; j < size; j++) { if (i != j) { Vector vector3 = vectors.get(j); d.set(vector3); d.subtract(vector2); double uLength = d.getDotProduct(u); double vLength = d.getDotProduct(v); uMaximum = Math.max(uLength, uMaximum); uMinimum = Math.min(uLength, uMinimum); vMaximum = Math.max(vLength, vMaximum); vMinimum = Math.min(vLength, vMinimum); } } double current = (uMaximum - uMinimum) * (vMaximum - vMinimum); if (current < minimum) { minimum = current; Vector origin = boundingBox.getOrigin(); origin.set(vector2); d.set(u); d.multiply(uMinimum); origin.add(d); d.set(v); d.multiply(vMinimum); origin.add(d); boundingBox.getU().set(u); boundingBox.getV().set(v); boundingBox.setHeight(vMaximum - vMinimum); boundingBox.setWidth(uMaximum - uMinimum); } } return boundingBox; }