private void parseLightBlock(SunflowAPI api) { p.checkNextToken("{"); p.checkNextToken("type"); if (p.peekNextToken("mesh")) { UI.printWarning(UI.Module.API, "Deprecated light type: mesh"); p.checkNextToken("name"); string name = p.getNextToken(); UI.printInfo(UI.Module.API, "Reading light mesh: {0} ...", name); p.checkNextToken("emit"); api.parameter("radiance", parseColor()); int samples = numLightSamples; if (p.peekNextToken("samples")) samples = p.getNextInt(); else UI.printWarning(UI.Module.API, "Samples keyword not found - defaulting to {0}", samples); api.parameter("samples", samples); int numVertices = p.getNextInt(); int numTriangles = p.getNextInt(); float[] points = new float[3 * numVertices]; int[] triangles = new int[3 * numTriangles]; for (int i = 0; i < numVertices; i++) { p.checkNextToken("v"); points[3 * i + 0] = p.getNextFloat(); points[3 * i + 1] = p.getNextFloat(); points[3 * i + 2] = p.getNextFloat(); // ignored p.getNextFloat(); p.getNextFloat(); p.getNextFloat(); p.getNextFloat(); p.getNextFloat(); } for (int i = 0; i < numTriangles; i++) { p.checkNextToken("t"); triangles[3 * i + 0] = p.getNextInt(); triangles[3 * i + 1] = p.getNextInt(); triangles[3 * i + 2] = p.getNextInt(); } api.parameter("points", "point", "vertex", points); api.parameter("triangles", triangles); TriangleMeshLight mesh = new TriangleMeshLight(); mesh.init(name, api); } else if (p.peekNextToken("point")) { UI.printInfo(UI.Module.API, "Reading point light ..."); Color pow; if (p.peekNextToken("color")) { pow = parseColor(); p.checkNextToken("power"); float po = p.getNextFloat(); pow.mul(po); } else { UI.printWarning(UI.Module.API, "Deprecated color specification - please use color and power instead"); p.checkNextToken("power"); pow = parseColor(); } p.checkNextToken("p"); api.parameter("center", parsePoint()); api.parameter("power", pow); api.light(api.getUniqueName("pointlight"), new PointLight()); } else if (p.peekNextToken("spherical")) { UI.printInfo(UI.Module.API, "Reading spherical light ..."); p.checkNextToken("color"); Color pow = parseColor(); p.checkNextToken("radiance"); pow.mul(p.getNextFloat()); api.parameter("radiance", pow); p.checkNextToken("center"); api.parameter("center", parsePoint()); p.checkNextToken("radius"); api.parameter("radius", p.getNextFloat()); p.checkNextToken("samples"); api.parameter("samples", p.getNextInt()); SphereLight light = new SphereLight(); light.init(api.getUniqueName("spherelight"), api); } else if (p.peekNextToken("directional")) { UI.printInfo(UI.Module.API, "Reading directional light ..."); p.checkNextToken("source"); Point3 s = parsePoint(); api.parameter("source", s); p.checkNextToken("target"); Point3 t = parsePoint(); api.parameter("dir", Point3.sub(t, s, new Vector3())); p.checkNextToken("radius"); api.parameter("radius", p.getNextFloat()); p.checkNextToken("emit"); Color e = parseColor(); if (p.peekNextToken("intensity")) { float i = p.getNextFloat(); e.mul(i); } else UI.printWarning(UI.Module.API, "Deprecated color specification - please use emit and intensity instead"); api.parameter("radiance", e); api.light(api.getUniqueName("dirlight"), new DirectionalSpotlight()); } else if (p.peekNextToken("ibl")) { UI.printInfo(UI.Module.API, "Reading image based light ..."); p.checkNextToken("image"); api.parameter("texture", p.getNextToken()); p.checkNextToken("center"); api.parameter("center", parseVector()); p.checkNextToken("up"); api.parameter("up", parseVector()); p.checkNextToken("lock"); api.parameter("fixed", p.getNextbool()); int samples = numLightSamples; if (p.peekNextToken("samples")) samples = p.getNextInt(); else UI.printWarning(UI.Module.API, "Samples keyword not found - defaulting to {0}", samples); api.parameter("samples", samples); ImageBasedLight ibl = new ImageBasedLight(); ibl.init(api.getUniqueName("ibl"), api); } else if (p.peekNextToken("meshlight")) { p.checkNextToken("name"); string name = p.getNextToken(); UI.printInfo(UI.Module.API, "Reading meshlight: {0} ...", name); p.checkNextToken("emit"); Color e = parseColor(); if (p.peekNextToken("radiance")) { float r = p.getNextFloat(); e.mul(r); } else UI.printWarning(UI.Module.API, "Deprecated color specification - please use emit and radiance instead"); api.parameter("radiance", e); int samples = numLightSamples; if (p.peekNextToken("samples")) samples = p.getNextInt(); else UI.printWarning(UI.Module.API, "Samples keyword not found - defaulting to {0}", samples); api.parameter("samples", samples); // parse vertices p.checkNextToken("points"); int np = p.getNextInt(); api.parameter("points", "point", "vertex", parseFloatArray(np * 3)); // parse triangle indices p.checkNextToken("triangles"); int nt = p.getNextInt(); api.parameter("triangles", parseIntArray(nt * 3)); TriangleMeshLight mesh = new TriangleMeshLight(); mesh.init(name, api); } else if (p.peekNextToken("sunsky")) { p.checkNextToken("up"); api.parameter("up", parseVector()); p.checkNextToken("east"); api.parameter("east", parseVector()); p.checkNextToken("sundir"); api.parameter("sundir", parseVector()); p.checkNextToken("turbidity"); api.parameter("turbidity", p.getNextFloat()); if (p.peekNextToken("samples")) api.parameter("samples", p.getNextInt()); SunSkyLight sunsky = new SunSkyLight(); sunsky.init(api.getUniqueName("sunsky"), api); } else UI.printWarning(UI.Module.API, "Unrecognized object type: {0}", p.getNextToken()); p.checkNextToken("}"); }
private void parseObjectBlock(SunflowAPI api) { p.checkNextToken("{"); bool noInstance = false; Matrix4 transform = null; string name = null; string[] shaders = null; string[] modifiers = null; if (p.peekNextToken("noinstance")) { // this indicates that the geometry is to be created, but not // instanced into the scene noInstance = true; } else { // these are the parameters to be passed to the instance if (p.peekNextToken("shaders")) { int n = p.getNextInt(); shaders = new string[n]; for (int i = 0; i < n; i++) shaders[i] = p.getNextToken(); } else { p.checkNextToken("shader"); shaders = new string[] { p.getNextToken() }; } if (p.peekNextToken("modifiers")) { int n = p.getNextInt(); modifiers = new string[n]; for (int i = 0; i < n; i++) modifiers[i] = p.getNextToken(); } else if (p.peekNextToken("modifier")) modifiers = new string[] { p.getNextToken() }; if (p.peekNextToken("transform")) transform = parseMatrix(); } if (p.peekNextToken("accel")) api.parameter("accel", p.getNextToken()); p.checkNextToken("type"); string type = p.getNextToken(); if (p.peekNextToken("name")) name = p.getNextToken(); else name = api.getUniqueName(type); if (type == "mesh") { UI.printWarning(UI.Module.API, "Deprecated object type: mesh"); UI.printInfo(UI.Module.API, "Reading mesh: {0} ...", name); int numVertices = p.getNextInt(); int numTriangles = p.getNextInt(); float[] points = new float[numVertices * 3]; float[] normals = new float[numVertices * 3]; float[] uvs = new float[numVertices * 2]; for (int i = 0; i < numVertices; i++) { p.checkNextToken("v"); points[3 * i + 0] = p.getNextFloat(); points[3 * i + 1] = p.getNextFloat(); points[3 * i + 2] = p.getNextFloat(); normals[3 * i + 0] = p.getNextFloat(); normals[3 * i + 1] = p.getNextFloat(); normals[3 * i + 2] = p.getNextFloat(); uvs[2 * i + 0] = p.getNextFloat(); uvs[2 * i + 1] = p.getNextFloat(); } int[] triangles = new int[numTriangles * 3]; for (int i = 0; i < numTriangles; i++) { p.checkNextToken("t"); triangles[i * 3 + 0] = p.getNextInt(); triangles[i * 3 + 1] = p.getNextInt(); triangles[i * 3 + 2] = p.getNextInt(); } // create geometry api.parameter("triangles", triangles); api.parameter("points", "point", "vertex", points); api.parameter("normals", "vector", "vertex", normals); api.parameter("uvs", "texcoord", "vertex", uvs); api.geometry(name, new TriangleMesh()); } else if (type == "flat-mesh") { UI.printWarning(UI.Module.API, "Deprecated object type: flat-mesh"); UI.printInfo(UI.Module.API, "Reading flat mesh: {0} ...", name); int numVertices = p.getNextInt(); int numTriangles = p.getNextInt(); float[] points = new float[numVertices * 3]; float[] uvs = new float[numVertices * 2]; for (int i = 0; i < numVertices; i++) { p.checkNextToken("v"); points[3 * i + 0] = p.getNextFloat(); points[3 * i + 1] = p.getNextFloat(); points[3 * i + 2] = p.getNextFloat(); p.getNextFloat(); p.getNextFloat(); p.getNextFloat(); uvs[2 * i + 0] = p.getNextFloat(); uvs[2 * i + 1] = p.getNextFloat(); } int[] triangles = new int[numTriangles * 3]; for (int i = 0; i < numTriangles; i++) { p.checkNextToken("t"); triangles[i * 3 + 0] = p.getNextInt(); triangles[i * 3 + 1] = p.getNextInt(); triangles[i * 3 + 2] = p.getNextInt(); } // create geometry api.parameter("triangles", triangles); api.parameter("points", "point", "vertex", points); api.parameter("uvs", "texcoord", "vertex", uvs); api.geometry(name, new TriangleMesh()); } else if (type == "sphere") { UI.printInfo(UI.Module.API, "Reading sphere ..."); api.geometry(name, new Sphere()); if (transform == null && !noInstance) { // legacy method of specifying transformation for spheres p.checkNextToken("c"); float x = p.getNextFloat(); float y = p.getNextFloat(); float z = p.getNextFloat(); p.checkNextToken("r"); float radius = p.getNextFloat(); api.parameter("transform", Matrix4.translation(x, y, z).multiply(Matrix4.scale(radius))); api.parameter("shaders", shaders); if (modifiers != null) api.parameter("modifiers", modifiers); api.instance(name + ".instance", name); noInstance = true; // disable future auto-instancing because // instance has already been created } } else if (type == "banchoff") { UI.printInfo(UI.Module.API, "Reading banchoff ..."); api.geometry(name, new BanchoffSurface()); } else if (type == "torus") { UI.printInfo(UI.Module.API, "Reading torus ..."); p.checkNextToken("r"); api.parameter("radiusInner", p.getNextFloat()); api.parameter("radiusOuter", p.getNextFloat()); api.geometry(name, new Torus()); } else if (type == "plane") { UI.printInfo(UI.Module.API, "Reading plane ..."); p.checkNextToken("p"); api.parameter("center", parsePoint()); if (p.peekNextToken("n")) { api.parameter("normal", parseVector()); } else { p.checkNextToken("p"); api.parameter("point1", parsePoint()); p.checkNextToken("p"); api.parameter("point2", parsePoint()); } api.geometry(name, new Plane()); } else if (type == "cornellbox") { UI.printInfo(UI.Module.API, "Reading cornell box ..."); if (transform != null) UI.printWarning(UI.Module.API, "Instancing is not supported on cornell box -- ignoring transform"); p.checkNextToken("corner0"); api.parameter("corner0", parsePoint()); p.checkNextToken("corner1"); api.parameter("corner1", parsePoint()); p.checkNextToken("left"); api.parameter("leftColor", parseColor()); p.checkNextToken("right"); api.parameter("rightColor", parseColor()); p.checkNextToken("top"); api.parameter("topColor", parseColor()); p.checkNextToken("bottom"); api.parameter("bottomColor", parseColor()); p.checkNextToken("back"); api.parameter("backColor", parseColor()); p.checkNextToken("emit"); api.parameter("radiance", parseColor()); if (p.peekNextToken("samples")) api.parameter("samples", p.getNextInt()); new CornellBox().init(name, api); noInstance = true; // instancing is handled natively by the init // method } else if (type == "generic-mesh") { UI.printInfo(UI.Module.API, "Reading generic mesh: {0} ... ", name); // parse vertices p.checkNextToken("points"); int np = p.getNextInt(); api.parameter("points", "point", "vertex", parseFloatArray(np * 3)); // parse triangle indices p.checkNextToken("triangles"); int nt = p.getNextInt(); api.parameter("triangles", parseIntArray(nt * 3)); // parse normals p.checkNextToken("normals"); if (p.peekNextToken("vertex")) api.parameter("normals", "vector", "vertex", parseFloatArray(np * 3)); else if (p.peekNextToken("facevarying")) api.parameter("normals", "vector", "facevarying", parseFloatArray(nt * 9)); else p.checkNextToken("none"); // parse texture coordinates p.checkNextToken("uvs"); if (p.peekNextToken("vertex")) api.parameter("uvs", "texcoord", "vertex", parseFloatArray(np * 2)); else if (p.peekNextToken("facevarying")) api.parameter("uvs", "texcoord", "facevarying", parseFloatArray(nt * 6)); else p.checkNextToken("none"); if (p.peekNextToken("face_shaders")) api.parameter("faceshaders", parseIntArray(nt)); api.geometry(name, new TriangleMesh()); } else if (type == "hair") { UI.printInfo(UI.Module.API, "Reading hair curves: {0} ... ", name); p.checkNextToken("segments"); api.parameter("segments", p.getNextInt()); p.checkNextToken("width"); api.parameter("widths", p.getNextFloat()); p.checkNextToken("points"); api.parameter("points", "point", "vertex", parseFloatArray(p.getNextInt())); api.geometry(name, new Hair()); } else if (type == "janino-tesselatable") { UI.printInfo(UI.Module.API, "Reading procedural primitive: {0} ... ", name); string code = p.getNextCodeBlock(); try { ITesselatable tess = null;//fixme:(Tesselatable) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(null, new stringReader(code)), Tesselatable.class, ClassLoader.getSystemClassLoader()); api.geometry(name, tess); } catch (Exception e) { UI.printDetailed(UI.Module.API, "Compiling: {0}", code); UI.printError(UI.Module.API, "{0}", e); noInstance = true; } } else if (type == "teapot") { UI.printInfo(UI.Module.API, "Reading teapot: {0} ... ", name); bool hasTesselationArguments = false; if (p.peekNextToken("subdivs")) { api.parameter("subdivs", p.getNextInt()); hasTesselationArguments = true; } if (p.peekNextToken("smooth")) { api.parameter("smooth", p.getNextbool()); hasTesselationArguments = true; } if (hasTesselationArguments) api.geometry(name, (ITesselatable)new Teapot()); else api.geometry(name, (PrimitiveList)new Teapot()); } else if (type == "gumbo") { UI.printInfo(UI.Module.API, "Reading gumbo:{0} ... ", name); bool hasTesselationArguments = false; if (p.peekNextToken("subdivs")) { api.parameter("subdivs", p.getNextInt()); hasTesselationArguments = true; } if (p.peekNextToken("smooth")) { api.parameter("smooth", p.getNextbool()); hasTesselationArguments = true; } if (hasTesselationArguments) api.geometry(name, (ITesselatable)new Gumbo()); else api.geometry(name, (PrimitiveList)new Gumbo()); } else if (type == "julia") { UI.printInfo(UI.Module.API, "Reading julia fractal: {0} ... ", name); if (p.peekNextToken("q")) { api.parameter("cw", p.getNextFloat()); api.parameter("cx", p.getNextFloat()); api.parameter("cy", p.getNextFloat()); api.parameter("cz", p.getNextFloat()); } if (p.peekNextToken("iterations")) api.parameter("iterations", p.getNextInt()); if (p.peekNextToken("epsilon")) api.parameter("epsilon", p.getNextFloat()); api.geometry(name, new JuliaFractal()); } else if (type == "particles" || type == "dlasurface") { if (type == "dlasurface") UI.printWarning(UI.Module.API, "Deprecated object type: \"dlasurface\" - please use \"particles\" instead"); p.checkNextToken("filename"); string filename = p.getNextToken(); bool littleEndian = false; if (p.peekNextToken("little_endian")) littleEndian = true; UI.printInfo(UI.Module.USER, "Loading particle file: {0}", filename); //File file = new File(filename); //FileInputStream stream = new FileInputStream(filename); //MappedByteBuffer map = stream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.Length()); //if (littleEndian) // map.order(ByteOrder.LITTLE_ENDIAN); //FloatBuffer buffer = map.asFloatBuffer(); BinaryReader reader = new BinaryReader(File.OpenRead(filename)); float[] data = new float[reader.BaseStream.Length / 4]; for (int i = 0; i < data.Length; i++) data[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);//buffer.get(i); reader.Close(); api.parameter("particles", "point", "vertex", data); if (p.peekNextToken("num")) api.parameter("num", p.getNextInt()); else api.parameter("num", data.Length / 3); p.checkNextToken("radius"); api.parameter("radius", p.getNextFloat()); api.geometry(name, new ParticleSurface()); } else if (type == "file-mesh") { UI.printInfo(UI.Module.API, "Reading file mesh: {0} ... ", name); p.checkNextToken("filename"); api.parameter("filename", p.getNextToken()); if (p.peekNextToken("smooth_normals")) api.parameter("smooth_normals", p.getNextbool()); api.geometry(name, new FileMesh()); } else if (type == "bezier-mesh") { UI.printInfo(UI.Module.API, "Reading bezier mesh: {0} ... ", name); p.checkNextToken("n"); int nu, nv; api.parameter("nu", nu = p.getNextInt()); api.parameter("nv", nv = p.getNextInt()); if (p.peekNextToken("wrap")) { api.parameter("uwrap", p.getNextbool()); api.parameter("vwrap", p.getNextbool()); } p.checkNextToken("points"); float[] points = new float[3 * nu * nv]; for (int i = 0; i < points.Length; i++) points[i] = p.getNextFloat(); api.parameter("points", "point", "vertex", points); if (p.peekNextToken("subdivs")) api.parameter("subdivs", p.getNextInt()); if (p.peekNextToken("smooth")) api.parameter("smooth", p.getNextbool()); api.geometry(name, (ITesselatable)new BezierMesh()); } else { UI.printWarning(UI.Module.API, "Unrecognized object type: {0}", p.getNextToken()); noInstance = true; } if (!noInstance) { // create instance api.parameter("shaders", shaders); if (modifiers != null) api.parameter("modifiers", modifiers); if (transform != null) api.parameter("transform", transform); api.instance(name + ".instance", name); } p.checkNextToken("}"); }
private void parseCamera(SunflowAPI api) { p.checkNextToken("{"); p.checkNextToken("type"); string type = p.getNextToken(); UI.printInfo(UI.Module.API, "Reading %s camera ...", type); parseCameraTransform(api); string name = api.getUniqueName("camera"); if (type == "pinhole") { p.checkNextToken("fov"); api.parameter("fov", p.getNextFloat()); p.checkNextToken("aspect"); api.parameter("aspect", p.getNextFloat()); api.camera(name, new PinholeLens()); } else if (type == "thinlens") { p.checkNextToken("fov"); api.parameter("fov", p.getNextFloat()); p.checkNextToken("aspect"); api.parameter("aspect", p.getNextFloat()); p.checkNextToken("fdist"); api.parameter("focus.distance", p.getNextFloat()); p.checkNextToken("lensr"); api.parameter("lens.radius", p.getNextFloat()); if (p.peekNextToken("sides")) api.parameter("lens.sides", p.getNextInt()); if (p.peekNextToken("rotation")) api.parameter("lens.rotation", p.getNextFloat()); api.camera(name, new ThinLens()); } else if (type == "spherical") { // no extra arguments api.camera(name, new SphericalLens()); } else if (type == "fisheye") { // no extra arguments api.camera(name, new FisheyeLens()); } else { UI.printWarning(UI.Module.API, "Unrecognized camera type: {0}", p.getNextToken()); p.checkNextToken("}"); return; } p.checkNextToken("}"); if (name != null) { api.parameter("camera", name); api.options(SunflowAPI.DEFAULT_OPTIONS); } }