📄 sunflowapi.java
字号:
/**
* Retrieve an instance object by its name, or <code>null</code> if no
* instance was found, or if the specified object is not an instance.
*
* @param name instance name
* @return the instance object associated with that name
*/
private final Instance lookupInstance(String name) {
return renderObjects.lookupInstance(name);
}
/**
* Retrieve a shader object by its name, or <code>null</code> if no shader
* was found, or if the specified object is not a shader.
*
* @param name camera name
* @return the camera object associate with that name
*/
private final Camera lookupCamera(String name) {
return renderObjects.lookupCamera(name);
}
private final Options lookupOptions(String name) {
return renderObjects.lookupOptions(name);
}
/**
* Retrieve a shader object by its name, or <code>null</code> if no shader
* was found, or if the specified object is not a shader.
*
* @param name shader name
* @return the shader object associated with that name
*/
public final Shader lookupShader(String name) {
return renderObjects.lookupShader(name);
}
/**
* Retrieve a modifier object by its name, or <code>null</code> if no
* modifier was found, or if the specified object is not a modifier.
*
* @param name modifier name
* @return the modifier object associated with that name
*/
public final Modifier lookupModifier(String name) {
return renderObjects.lookupModifier(name);
}
/**
* Retrieve a light object by its name, or <code>null</code> if no shader
* was found, or if the specified object is not a light.
*
* @param name light name
* @return the light object associated with that name
*/
private final LightSource lookupLight(String name) {
return renderObjects.lookupLight(name);
}
/**
* Sets a global shader override to the specified shader name. If the shader
* is not found, the overriding is disabled. The second parameter controls
* whether the override applies to the photon tracing process.
*
* @param name shader name
* @param photonOverride apply override to photon tracing phase
*/
public final void shaderOverride(String name, boolean photonOverride) {
scene.setShaderOverride(lookupShader(name), photonOverride);
}
/**
* Render using the specified options and the specified display. If the
* specified options do not exist - defaults will be used.
*
* @param optionsName name of the {@link RenderObject} which contains the
* options
* @param display display object
*/
public final void render(String optionsName, Display display) {
renderObjects.updateScene(scene);
Options opt = lookupOptions(optionsName);
if (opt == null)
opt = new Options();
scene.setCamera(lookupCamera(opt.getString("camera", null)));
// baking
String bakingInstanceName = opt.getString("baking.instance", null);
if (bakingInstanceName != null) {
Instance bakingInstance = lookupInstance(bakingInstanceName);
if (bakingInstance == null) {
UI.printError(Module.API, "Unable to bake instance \"%s\" - not found", bakingInstanceName);
return;
}
scene.setBakingInstance(bakingInstance);
} else
scene.setBakingInstance(null);
String samplerName = opt.getString("sampler", "bucket");
ImageSampler sampler = null;
if (samplerName.equals("none") || samplerName.equals("null"))
sampler = null;
else if (samplerName.equals("bucket"))
sampler = bucketRenderer;
else if (samplerName.equals("ipr"))
sampler = progressiveRenderer;
else if (samplerName.equals("fast"))
sampler = new SimpleRenderer();
else {
UI.printError(Module.API, "Unknown sampler type: %s - aborting", samplerName);
return;
}
scene.render(opt, sampler, display);
}
/**
* Parse the specified filename. The include paths are searched first. The
* contents of the file are simply added to the active scene. This allows to
* break up a scene into parts, even across file formats. The appropriate
* parser is chosen based on file extension.
*
* @param filename filename to load
* @return <code>true</code> upon sucess, <code>false</code> if an error
* occured.
*/
public final boolean parse(String filename) {
if (filename == null)
return false;
filename = includeSearchPath.resolvePath(filename);
SceneParser parser = null;
if (filename.endsWith(".sc"))
parser = new SCParser();
else if (filename.endsWith(".ra2"))
parser = new RA2Parser();
else if (filename.endsWith(".ra3"))
parser = new RA3Parser();
else if (filename.endsWith(".tri"))
parser = new TriParser();
else if (filename.endsWith(".rib"))
parser = new ShaveRibParser();
else {
UI.printError(Module.API, "Unable to find a suitable parser for: \"%s\"", filename);
return false;
}
String currentFolder = new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
includeSearchPath.addSearchPath(currentFolder);
textureSearchPath.addSearchPath(currentFolder);
return parser.parse(filename, this);
}
/**
* Retrieve the bounding box of the scene. This method will be valid only
* after a first call to {@link #render(String, Display)} has been made.
*/
public final BoundingBox getBounds() {
return scene.getBounds();
}
/**
* This method does nothing, but may be overriden to create scenes
* procedurally.
*/
public void build() {
}
/**
* Create an API object from the specified file. Java files are read by
* Janino and are expected to implement a build method (they implement a
* derived class of SunflowAPI. The build method is called if the code
* compiles succesfully. Other files types are handled by the parse method.
*
* @param filename filename to load
* @return a valid SunflowAPI object or <code>null</code> on failure
*/
public static SunflowAPI create(String filename, int frameNumber) {
if (filename == null)
return new SunflowAPI();
SunflowAPI api = null;
if (filename.endsWith(".java")) {
Timer t = new Timer();
UI.printInfo(Module.API, "Compiling \"" + filename + "\" ...");
t.start();
try {
FileInputStream stream = new FileInputStream(filename);
api = (SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(filename, stream), SunflowAPI.class, ClassLoader.getSystemClassLoader());
stream.close();
} catch (CompileException e) {
UI.printError(Module.API, "Could not compile: \"%s\"", filename);
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (ParseException e) {
UI.printError(Module.API, "Could not compile: \"%s\"", filename);
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (ScanException e) {
UI.printError(Module.API, "Could not compile: \"%s\"", filename);
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (IOException e) {
UI.printError(Module.API, "Could not compile: \"%s\"", filename);
UI.printError(Module.API, "%s", e.getMessage());
return null;
}
t.end();
UI.printInfo(Module.API, "Compile time: " + t.toString());
if (api != null) {
String currentFolder = new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
api.includeSearchPath.addSearchPath(currentFolder);
api.textureSearchPath.addSearchPath(currentFolder);
}
UI.printInfo(Module.API, "Build script running ...");
t.start();
api.setCurrentFrame(frameNumber);
api.build();
t.end();
UI.printInfo(Module.API, "Build script time: %s", t.toString());
} else {
api = new SunflowAPI();
api = api.parse(filename) ? api : null;
}
return api;
}
/**
* Compile the specified code string via Janino. The code must implement a
* build method as described above. The build method is not called on the
* output, it is up the caller to do so.
*
* @param code java code string
* @return a valid SunflowAPI object upon succes, <code>null</code>
* otherwise.
*/
public static SunflowAPI compile(String code) {
try {
Timer t = new Timer();
t.start();
SunflowAPI api = (SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(null, new StringReader(code)), SunflowAPI.class, (ClassLoader) null);
t.end();
UI.printInfo(Module.API, "Compile time: %s", t.toString());
return api;
} catch (CompileException e) {
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (ParseException e) {
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (ScanException e) {
UI.printError(Module.API, "%s", e.getMessage());
return null;
} catch (IOException e) {
UI.printError(Module.API, "%s", e.getMessage());
return null;
}
}
/**
* Read the value of the current frame. This value is intended only for
* procedural animation creation. It is not used by the Sunflow core in
* anyway. The default value is 1.
*
* @return current frame number
*/
public int getCurrentFrame() {
return currentFrame;
}
/**
* Set the value of the current frame. This value is intended only for
* procedural animation creation. It is not used by the Sunflow core in
* anyway. The default value is 1.
*
* @param currentFrame current frame number
*/
public void setCurrentFrame(int currentFrame) {
this.currentFrame = currentFrame;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -