⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scparser.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package org.sunflow.core.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

import org.codehaus.janino.ClassBodyEvaluator;
import org.codehaus.janino.CompileException;
import org.codehaus.janino.Scanner;
import org.codehaus.janino.Parser.ParseException;
import org.codehaus.janino.Scanner.ScanException;
import org.sunflow.SunflowAPI;
import org.sunflow.core.PrimitiveList;
import org.sunflow.core.SceneParser;
import org.sunflow.core.Shader;
import org.sunflow.core.Tesselatable;
import org.sunflow.core.camera.FisheyeLens;
import org.sunflow.core.camera.PinholeLens;
import org.sunflow.core.camera.SphericalLens;
import org.sunflow.core.camera.ThinLens;
import org.sunflow.core.light.DirectionalSpotlight;
import org.sunflow.core.light.ImageBasedLight;
import org.sunflow.core.light.PointLight;
import org.sunflow.core.light.SphereLight;
import org.sunflow.core.light.SunSkyLight;
import org.sunflow.core.light.TriangleMeshLight;
import org.sunflow.core.modifiers.BumpMappingModifier;
import org.sunflow.core.modifiers.NormalMapModifier;
import org.sunflow.core.primitive.Background;
import org.sunflow.core.primitive.BanchoffSurface;
import org.sunflow.core.primitive.CornellBox;
import org.sunflow.core.primitive.Hair;
import org.sunflow.core.primitive.JuliaFractal;
import org.sunflow.core.primitive.ParticleSurface;
import org.sunflow.core.primitive.Plane;
import org.sunflow.core.primitive.Sphere;
import org.sunflow.core.primitive.Torus;
import org.sunflow.core.primitive.TriangleMesh;
import org.sunflow.core.shader.AmbientOcclusionShader;
import org.sunflow.core.shader.AnisotropicWardShader;
import org.sunflow.core.shader.ConstantShader;
import org.sunflow.core.shader.DiffuseShader;
import org.sunflow.core.shader.GlassShader;
import org.sunflow.core.shader.IDShader;
import org.sunflow.core.shader.MirrorShader;
import org.sunflow.core.shader.PhongShader;
import org.sunflow.core.shader.ShinyDiffuseShader;
import org.sunflow.core.shader.TexturedAmbientOcclusionShader;
import org.sunflow.core.shader.TexturedDiffuseShader;
import org.sunflow.core.shader.TexturedPhongShader;
import org.sunflow.core.shader.TexturedShinyDiffuseShader;
import org.sunflow.core.shader.TexturedWardShader;
import org.sunflow.core.shader.UberShader;
import org.sunflow.core.shader.ViewCausticsShader;
import org.sunflow.core.shader.ViewGlobalPhotonsShader;
import org.sunflow.core.shader.ViewIrradianceShader;
import org.sunflow.core.tesselatable.BezierMesh;
import org.sunflow.core.tesselatable.FileMesh;
import org.sunflow.core.tesselatable.Gumbo;
import org.sunflow.core.tesselatable.Teapot;
import org.sunflow.image.Color;
import org.sunflow.math.Matrix4;
import org.sunflow.math.Point3;
import org.sunflow.math.Vector3;
import org.sunflow.system.Parser;
import org.sunflow.system.Timer;
import org.sunflow.system.UI;
import org.sunflow.system.Parser.ParserException;
import org.sunflow.system.UI.Module;

/**
 * This class provides a static method for loading files in the Sunflow scene
 * file format.
 */
public class SCParser implements SceneParser {
    private Parser p;
    private int numLightSamples;

    public SCParser() {
    }

    public boolean parse(String filename, SunflowAPI api) {
        String localDir = new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
        numLightSamples = 1;
        Timer timer = new Timer();
        timer.start();
        UI.printInfo(Module.API, "Parsing \"%s\" ...", filename);
        try {
            p = new Parser(filename);
            while (true) {
                String token = p.getNextToken();
                if (token == null)
                    break;
                if (token.equals("image")) {
                    UI.printInfo(Module.API, "Reading image settings ...");
                    parseImageBlock(api);
                } else if (token.equals("background")) {
                    UI.printInfo(Module.API, "Reading background ...");
                    parseBackgroundBlock(api);
                } else if (token.equals("accel")) {
                    UI.printInfo(Module.API, "Reading accelerator type ...");
                    p.getNextToken();
                    UI.printWarning(Module.API, "Setting accelerator type is not recommended - ignoring");
                } else if (token.equals("filter")) {
                    UI.printInfo(Module.API, "Reading image filter type ...");
                    parseFilter(api);
                } else if (token.equals("bucket")) {
                    UI.printInfo(Module.API, "Reading bucket settings ...");
                    api.parameter("bucket.size", p.getNextInt());
                    api.parameter("bucket.order", p.getNextToken());
                    api.options(SunflowAPI.DEFAULT_OPTIONS);
                } else if (token.equals("photons")) {
                    UI.printInfo(Module.API, "Reading photon settings ...");
                    parsePhotonBlock(api);
                } else if (token.equals("gi")) {
                    UI.printInfo(Module.API, "Reading global illumination settings ...");
                    parseGIBlock(api);
                } else if (token.equals("lightserver")) {
                    UI.printInfo(Module.API, "Reading light server settings ...");
                    parseLightserverBlock(api);
                } else if (token.equals("trace-depths")) {
                    UI.printInfo(Module.API, "Reading trace depths ...");
                    parseTraceBlock(api);
                } else if (token.equals("camera")) {
                    parseCamera(api);
                } else if (token.equals("shader")) {
                    if (!parseShader(api))
                        return false;
                } else if (token.equals("modifier")) {
                    if (!parseModifier(api))
                        return false;
                } else if (token.equals("override")) {
                    api.shaderOverride(p.getNextToken(), p.getNextBoolean());
                } else if (token.equals("object")) {
                    parseObjectBlock(api);
                } else if (token.equals("instance")) {
                    parseInstanceBlock(api);
                } else if (token.equals("light")) {
                    parseLightBlock(api);
                } else if (token.equals("texturepath")) {
                    String path = p.getNextToken();
                    if (!new File(path).isAbsolute())
                        path = localDir + File.separator + path;
                    api.addTextureSearchPath(path);
                } else if (token.equals("includepath")) {
                    String path = p.getNextToken();
                    if (!new File(path).isAbsolute())
                        path = localDir + File.separator + path;
                    api.addIncludeSearchPath(path);
                } else if (token.equals("include")) {
                    String file = p.getNextToken();
                    UI.printInfo(Module.API, "Including: \"%s\" ...", file);
                    api.parse(file);
                } else
                    UI.printWarning(Module.API, "Unrecognized token %s", token);
            }
            p.close();
        } catch (ParserException e) {
            UI.printError(Module.API, "%s", e.getMessage());
            e.printStackTrace();
            return false;
        } catch (FileNotFoundException e) {
            UI.printError(Module.API, "%s", e.getMessage());
            return false;
        } catch (IOException e) {
            UI.printError(Module.API, "%s", e.getMessage());
            return false;
        }
        timer.end();
        UI.printInfo(Module.API, "Done parsing.");
        UI.printInfo(Module.API, "Parsing time: %s", timer.toString());
        return true;
    }

    private void parseImageBlock(SunflowAPI api) throws IOException, ParserException {
        p.checkNextToken("{");
        if (p.peekNextToken("resolution")) {
            api.parameter("resolutionX", p.getNextInt());
            api.parameter("resolutionY", p.getNextInt());
        }
        if (p.peekNextToken("aa")) {
            api.parameter("aa.min", p.getNextInt());
            api.parameter("aa.max", p.getNextInt());
        }
        if (p.peekNextToken("samples"))
            api.parameter("aa.samples", p.getNextInt());
        if (p.peekNextToken("contrast"))
            api.parameter("aa.contrast", p.getNextFloat());
        if (p.peekNextToken("filter"))
            api.parameter("filter", p.getNextToken());
        if (p.peekNextToken("jitter"))
            api.parameter("aa.jitter", p.getNextBoolean());
        if (p.peekNextToken("show-aa")) {
            UI.printWarning(Module.API, "Deprecated: show-aa ignored");
            p.getNextBoolean();
        }
        if (p.peekNextToken("output")) {
            UI.printWarning(Module.API, "Deprecated: output statement ignored");
            p.getNextToken();
        }
        api.options(SunflowAPI.DEFAULT_OPTIONS);
        p.checkNextToken("}");
    }

    private void parseBackgroundBlock(SunflowAPI api) throws IOException, ParserException {
        p.checkNextToken("{");
        p.checkNextToken("color");
        api.parameter("color", parseColor());
        api.shader("background.shader", new ConstantShader());
        api.geometry("background", new Background());
        api.parameter("shaders", "background.shader");
        api.instance("background.instance", "background");
        p.checkNextToken("}");
    }

    private void parseFilter(SunflowAPI api) throws IOException, ParserException {
        UI.printWarning(Module.API, "Deprecated keyword \"filter\" - set this option in the image block");
        String name = p.getNextToken();
        api.parameter("filter", name);
        api.options(SunflowAPI.DEFAULT_OPTIONS);
        boolean hasSizeParams = name.equals("box") || name.equals("gaussian") || name.equals("blackman-harris") || name.equals("sinc") || name.equals("triangle");
        if (hasSizeParams) {
            p.getNextFloat();
            p.getNextFloat();
        }
    }

    private void parsePhotonBlock(SunflowAPI api) throws ParserException, IOException {
        int numEmit = 0;
        boolean globalEmit = false;
        p.checkNextToken("{");
        if (p.peekNextToken("emit")) {
            UI.printWarning(Module.API, "Shared photon emit values are deprectated - specify number of photons to emit per map");
            numEmit = p.getNextInt();
            globalEmit = true;
        }
        if (p.peekNextToken("global")) {
            UI.printWarning(Module.API, "Global photon map setting belonds inside the gi block - ignoring");
            if (!globalEmit)
                p.getNextInt();
            p.getNextToken();
            p.getNextInt();
            p.getNextFloat();
        }
        p.checkNextToken("caustics");
        if (!globalEmit)
            numEmit = p.getNextInt();
        api.parameter("caustics.emit", numEmit);
        api.parameter("caustics", p.getNextToken());
        api.parameter("caustics.gather", p.getNextInt());
        api.parameter("caustics.radius", p.getNextFloat());
        api.options(SunflowAPI.DEFAULT_OPTIONS);
        p.checkNextToken("}");
    }

    private void parseGIBlock(SunflowAPI api) throws ParserException, IOException {
        p.checkNextToken("{");
        p.checkNextToken("type");
        if (p.peekNextToken("irr-cache")) {
            api.parameter("gi.engine", "irr-cache");
            p.checkNextToken("samples");
            api.parameter("gi.irr-cache.samples", p.getNextInt());
            p.checkNextToken("tolerance");
            api.parameter("gi.irr-cache.tolerance", p.getNextFloat());
            p.checkNextToken("spacing");
            api.parameter("gi.irr-cache.min_spacing", p.getNextFloat());
            api.parameter("gi.irr-cache.max_spacing", p.getNextFloat());
            // parse global photon map info
            if (p.peekNextToken("global")) {
                api.parameter("gi.irr-cache.gmap.emit", p.getNextInt());
                api.parameter("gi.irr-cache.gmap", p.getNextToken());
                api.parameter("gi.irr-cache.gmap.gather", p.getNextInt());
                api.parameter("gi.irr-cache.gmap.radius", p.getNextFloat());
            }
        } else if (p.peekNextToken("path")) {
            api.parameter("gi.engine", "path");
            p.checkNextToken("samples");
            api.parameter("gi.path.samples", p.getNextInt());
            if (p.peekNextToken("bounces")) {
                UI.printWarning(Module.API, "Deprecated setting: bounces - use diffuse trace depth instead");
                p.getNextInt();
            }
        } else if (p.peekNextToken("fake")) {
            api.parameter("gi.engine", "fake");
            p.checkNextToken("up");
            api.parameter("gi.fake.up", parseVector());
            p.checkNextToken("sky");
            api.parameter("gi.fake.sky", parseColor());
            p.checkNextToken("ground");
            api.parameter("gi.fake.ground", parseColor());
        } else if (p.peekNextToken("igi")) {
            api.parameter("gi.engine", "igi");
            p.checkNextToken("samples");
            api.parameter("gi.igi.samples", p.getNextInt());
            p.checkNextToken("sets");
            api.parameter("gi.igi.sets", p.getNextInt());
            if (!p.peekNextToken("b"))
                p.checkNextToken("c");
            api.parameter("gi.igi.c", p.getNextFloat());
            p.checkNextToken("bias-samples");
            api.parameter("gi.igi.bias_samples", p.getNextInt());
        } else if (p.peekNextToken("ambocc")) {
            api.parameter("gi.engine", "ambocc");
            p.checkNextToken("bright");
            api.parameter("gi.ambocc.bright", parseColor());
            p.checkNextToken("dark");
            api.parameter("gi.ambocc.dark", parseColor());
            p.checkNextToken("samples");
            api.parameter("gi.ambocc.samples", p.getNextInt());
            if (p.peekNextToken("maxdist"))
                api.parameter("gi.ambocc.maxdist", p.getNextFloat());
        } else if (p.peekNextToken("none") || p.peekNextToken("null")) {
            // disable GI
            api.parameter("gi.engine", "none");
        } else
            UI.printWarning(Module.API, "Unrecognized gi engine type \"%s\" - ignoring", p.getNextToken());
        api.options(SunflowAPI.DEFAULT_OPTIONS);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -