diff -Nru sunflow/buildForSweetHome3D.xml sunflow-0.07.3g-src-diff/buildForSweetHome3D.xml --- sunflow/buildForSweetHome3D.xml 1970-01-01 01:00:00.000000000 +0100 +++ sunflow-0.07.3g-src-diff/buildForSweetHome3D.xml 2011-03-13 01:10:20.000000000 +0100 @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="Sunflow" default="jars"> + <!-- This needs to change with every release --> + <property name="sunflow.version" value="0.07.3" /> + <property name="sunflow.jdk.level" value="5" /> + <property name="sunflow.zip.comment" value="Sunflow rendering system v${sunflow.version}" /> + <property name="sunflow.libs" value="janino.jar" /> + <property name="sunflow.jar.filename" value="sunflow-0.07.3g.jar" /> + + <!-- Basic targets --> + <target name="init"> + <property name="src.dir" value="src" /> + <property name="resources.dir" value="resources" /> + <available file="${resources.dir}" type="dir" property="resources.present" /> + <property name="build.dir" value="build" /> + <property name="release.dir" value="release" /> + <!-- build folder contains temporary files needed to create release level files --> + <property name="build.classes.dir" value="${build.dir}/classes" /> + <property name="build.manifest" value="${build.dir}/sunflow.mf" /> + <property name="build.jar" value="${build.dir}/sunflow.jar" /> + <!-- release folder contains files which may be distributed in some way or another --> + <property name="release.javadoc.dir" value="${release.dir}/javadoc" /> + <property name="release.src.zip" value="${release.dir}/sunflow-src-v${sunflow.version}.zip" /> + <property name="release.bin.zip" value="${release.dir}/sunflow-bin-v${sunflow.version}.zip" /> + <property name="release.data.zip" value="${release.dir}/sunflow-data-v${sunflow.version}.zip" /> + </target> + + <target name="clean" depends="init" description="Remove build files created this scripts"> + <delete dir="${build.dir}" /> + <delete dir="${release.dir}" /> + </target> + + + <!-- build directory targets --> + <target name="compile" depends="init" description="Compile source"> + <mkdir dir="${build.classes.dir}" /> + <javac srcdir="${src.dir}" destdir="${build.classes.dir}" source="${sunflow.jdk.level}" target="${sunflow.jdk.level}" classpath="${sunflow.libs}"> + <compilerarg value="-Xlint:unchecked" /> + </javac> + </target> + + <target name="create_manifest" description="Create the Sunflow jar manifest"> + <echo file="${build.manifest}" append="false" message="Manifest-Version: 1.0${line.separator}" /> + </target> + + <target name="jars" depends="clean, compile, create_manifest" if="resources.present" description="Create jar files required for execution"> + <mkdir dir="${release.dir}" /> + <jar jarfile="${release.dir}/${sunflow.jar.filename}" manifest="${build.manifest}"> + <fileset dir="${build.classes.dir}" > + <include name="**"/> + <exclude name="org/sunflow/core/parser/**"/> + <exclude name="**/RenderGlobalsPanel*.class"/> + <exclude name="**/Benchmark*.class"/> + <exclude name="**/ImagePanel*.class"/> + <exclude name="**/*FileSunflowAPI*.class"/> + <exclude name="SunflowGUI*.class"/> + </fileset> + </jar> + </target> +</project> \ Manca newline alla fine del file diff -Nru sunflow/README.TXT sunflow-0.07.3g-src-diff/README.TXT --- sunflow/README.TXT 1970-01-01 01:00:00.000000000 +0100 +++ sunflow-0.07.3g-src-diff/README.TXT 2011-03-13 01:09:50.000000000 +0100 @@ -0,0 +1,12 @@ +SUNFLOW v 0.07.3g +----------------- + +This archive contains the SunFlow files modified for Sweet Home 3D, compared to the revision 396 of SunFlow repository available on SourceForge.net with the following command: + svn co -r 396 https://sunflow.svn.sourceforge.net/svnroot/sunflow/trunk sunflow + +sunflow-0.07.3g.jar can be built with the following ant command: + ant -f buildForSweetHome3D.xml + + +Note: differences in source code are marked with comments starting by + // EP \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/accel/BoundingIntervalHierarchy.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/accel/BoundingIntervalHierarchy.java --- sunflow/src/org/sunflow/core/accel/BoundingIntervalHierarchy.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/accel/BoundingIntervalHierarchy.java 2011-02-13 00:12:06.000000000 +0100 @@ -177,7 +177,13 @@ float clipL = Float.NaN, clipR = Float.NaN, prevClip = Float.NaN; float split = Float.NaN, prevSplit; boolean wasLeft = true; - while (true) { + // EP : Added a loop counter to avoid endless loop + float[] gridBoxCopy = gridBox.clone(); + float[] nodeBoxCopy = nodeBox.clone(); + int loopCount = 0; + // EP : End of modification + do { + // while (true) { prevAxis = axis; prevSplit = split; // perform quick consistency checks @@ -256,7 +262,8 @@ // ensure we are making progress in the subdivision if (right == rightOrig) { // all left - if (clipL <= split) { + // EP : Added additional test to avoid endless loop + if (clipL < split || (clipL == split && !(prevAxis == axis && prevSplit == split))) { // keep looping on left half gridBox[2 * axis + 1] = split; prevClip = clipL; @@ -274,7 +281,8 @@ } else if (left > right) { // all right right = rightOrig; - if (clipR >= split) { + // EP : Added additional test to avoid endless loop + if (clipR > split || (clipR == split && !(prevAxis == axis && prevSplit == split))) { // keep looping on right half gridBox[2 * axis + 0] = split; prevClip = clipR; @@ -322,7 +330,15 @@ } break; } + // EP : Added test to avoid endless loop + } while (loopCount++ < 100); + if (loopCount > 100) { + System.arraycopy(gridBoxCopy, 0, gridBox, 0, gridBox.length); + System.arraycopy(nodeBoxCopy, 0, nodeBox, 0, nodeBox.length); + return; } + // EP : End of modification + // compute index of child nodes int nextIndex = tempTree.getSize(); // allocate left node @@ -482,8 +498,13 @@ intervalMax = (tf <= intervalMax) ? tf : intervalMax; continue; } + // EP : Give up if stack is full + if (stackPos == stack.length) { + break pushloop; + } + // EP : End of modification // ray passes through both nodes - // push back node + // push back node stack[stackPos].node = back; stack[stackPos].near = (tb >= intervalMin) ? tb : intervalMin; stack[stackPos].far = intervalMax; @@ -511,6 +532,11 @@ intervalMax = (tf <= intervalMax) ? tf : intervalMax; continue; } + // EP : Give up if stack is full + if (stackPos == stack.length) { + break pushloop; + } + // EP : End of modification // ray passes through both nodes // push back node stack[stackPos].node = back; @@ -541,6 +567,11 @@ intervalMax = (tf <= intervalMax) ? tf : intervalMax; continue; } + // EP : Give up if stack is full + if (stackPos == stack.length) { + break pushloop; + } + // EP : End of modification // ray passes through both nodes // push back node stack[stackPos].node = back; @@ -597,7 +628,12 @@ } // traversal loop do { // stack is empty? - if (stackPos == 0) + if (stackPos == 0 + // EP : Check ray values aren't NaN + || Float.isNaN(r.dx) + || Float.isNaN(r.dy) + || Float.isNaN(r.dz)) + // EP : End of modification return; // move back up the stack stackPos--; diff -Nru sunflow/src/org/sunflow/core/light/ImageBasedLight.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/ImageBasedLight.java --- sunflow/src/org/sunflow/core/light/ImageBasedLight.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/ImageBasedLight.java 2010-06-20 22:18:44.000000000 +0200 @@ -11,7 +11,6 @@ import org.sunflow.core.Shader; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Bitmap; import org.sunflow.image.Color; import org.sunflow.math.BoundingBox; @@ -55,7 +54,8 @@ numLowSamples = pl.getInt("lowsamples", numLowSamples); String filename = pl.getString("texture", null); if (filename != null) - texture = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + texture = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); // no texture provided if (texture == null) @@ -272,4 +272,14 @@ public Instance createInstance() { return Instance.createTemporary(this, null, this); } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/light/SphereLight.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/SphereLight.java --- sunflow/src/org/sunflow/core/light/SphereLight.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/SphereLight.java 2010-06-20 22:18:44.000000000 +0200 @@ -150,4 +150,14 @@ public Instance createInstance() { return Instance.createTemporary(new Sphere(), Matrix4.translation(center.x, center.y, center.z).multiply(Matrix4.scale(radius)), this); } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/light/SunSkyLight.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/SunSkyLight.java --- sunflow/src/org/sunflow/core/light/SunSkyLight.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/SunSkyLight.java 2010-10-08 19:38:16.000000000 +0200 @@ -315,6 +315,12 @@ return getSkyRGB(basis.untransform(state.getRay().getDirection())).constrainRGB(); } + // EP : Reused sun sky color + public Color getSunColor() { + return getSkyRGB(basis.untransform(sunDirWorld)).constrainRGB(); + } + // EP : End of modification + public void scatterPhoton(ShadingState state, Color power) { // let photon escape } @@ -334,4 +340,14 @@ public Instance createInstance() { return Instance.createTemporary(this, null, this); } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/light/TriangleMeshLight.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/TriangleMeshLight.java --- sunflow/src/org/sunflow/core/light/TriangleMeshLight.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/light/TriangleMeshLight.java 2010-06-20 22:18:44.000000000 +0200 @@ -269,4 +269,14 @@ } } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/LightServer.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/LightServer.java --- sunflow/src/org/sunflow/core/LightServer.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/LightServer.java 2010-12-04 18:53:08.000000000 +0100 @@ -24,12 +24,15 @@ private int maxDiffuseDepth; private int maxReflectionDepth; private int maxRefractionDepth; + // EP : Added transparency management + private int maxTransparencyDepth; // indirect illumination private CausticPhotonMapInterface causticPhotonMap; private GIEngine giEngine; private int photonCounter; + LightServer(Scene scene) { this.scene = scene; lights = new LightSource[0]; @@ -41,6 +44,8 @@ maxDiffuseDepth = 1; maxReflectionDepth = 4; maxRefractionDepth = 4; + // EP : Added transparency management + maxTransparencyDepth = 4; causticPhotonMap = null; giEngine = null; @@ -64,6 +69,8 @@ maxDiffuseDepth = options.getInt("depths.diffuse", maxDiffuseDepth); maxReflectionDepth = options.getInt("depths.reflection", maxReflectionDepth); maxRefractionDepth = options.getInt("depths.refraction", maxRefractionDepth); + // EP : Added transparency management + maxTransparencyDepth = options.getInt("depths.transparency", maxTransparencyDepth); String giEngineType = options.getString("gi.engine", null); giEngine = PluginRegistry.giEnginePlugins.createObject(giEngineType); String caustics = options.getString("caustics", null); @@ -143,7 +150,8 @@ synchronized (LightServer.this) { UI.taskUpdate(photonCounter); photonCounter++; - if (UI.taskCanceled()) + // EP : Manage renderer stop with interruptions + if (Thread.currentThread().isInterrupted()) return; } @@ -176,18 +184,19 @@ photonThreads[i].setPriority(scene.getThreadPriority()); photonThreads[i].start(); } - for (int i = 0; i < photonThreads.length; i++) { - try { + // EP : Moved InterruptedException out of loop to be able to stop all rendering threads + try { + for (int i = 0; i < photonThreads.length; i++) { photonThreads[i].join(); - } catch (InterruptedException e) { - UI.printError(Module.LIGHT, "Photon thread %d of %d was interrupted", i + 1, photonThreads.length); - return false; } - } - if (UI.taskCanceled()) { - UI.taskStop(); // shut down task cleanly + } catch (InterruptedException e) { + for (int i = 0; i < photonThreads.length; i++) { + photonThreads[i].interrupt(); + } + UI.printError(Module.BCKT, "Photon thread was interrupted"); return false; } + // EP : End of modification photonTimer.end(); UI.taskStop(); UI.printInfo(Module.LIGHT, "Tracing time for %s photons: %s", type, photonTimer.toString()); @@ -294,7 +303,7 @@ Color shadeHit(ShadingState state) { state.getInstance().prepareShadingState(state); Shader shader = getShader(state); - return (shader != null) ? shader.getRadiance(state) : Color.BLACK; + return (shader != null) ? shader.getRadiance(state) : Color.BLACK; } Color traceGlossy(ShadingState previous, Ray r, int i) { @@ -357,4 +366,28 @@ if (causticPhotonMap != null) causticPhotonMap.getSamples(state); } + + // EP : Added transparency management + Color traceShadow(Ray r, ShadingState previous) { + float maxDist = r.getMax(); + scene.traceShadow(r, previous.getIntersectionState()); + if (previous.getIntersectionState().hit()) { + Shader previousShader = previous.getIntersectionState().instance.getShader(0); + if (previousShader == null || previousShader.isOpaque() || previous.getShadowDepth() >= maxTransparencyDepth) { + return Color.WHITE; // fully opaque hit + } + ShadingState sstate = ShadingState.createShadowState(previous, r); + sstate.getInstance().prepareShadingState(sstate); + Shader shader = getShader(sstate); + if (shader == null || shader.isOpaque()) + return Color.WHITE; + Color opac = shader.getOpacity(sstate); + if (opac.isWhite()) + return opac; + else + return opac.copy().madd(Color.sub(Color.WHITE, opac), sstate.traceTransparentShadow(maxDist)); + } else + return Color.BLACK; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/modifiers/BumpMappingModifier.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/modifiers/BumpMappingModifier.java --- sunflow/src/org/sunflow/core/modifiers/BumpMappingModifier.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/modifiers/BumpMappingModifier.java 2010-06-20 22:18:46.000000000 +0200 @@ -5,7 +5,6 @@ import org.sunflow.core.ParameterList; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.math.OrthoNormalBasis; public class BumpMappingModifier implements Modifier { @@ -20,7 +19,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - bumpTexture = TextureCache.getTexture(api.resolveTextureFilename(filename), true); + // EP : Made texture cache local to a SunFlow API instance + bumpTexture = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), true); scale = pl.getFloat("scale", scale); return bumpTexture != null; } diff -Nru sunflow/src/org/sunflow/core/modifiers/NormalMapModifier.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/modifiers/NormalMapModifier.java --- sunflow/src/org/sunflow/core/modifiers/NormalMapModifier.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/modifiers/NormalMapModifier.java 2010-06-20 22:18:46.000000000 +0200 @@ -5,7 +5,6 @@ import org.sunflow.core.ParameterList; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.math.OrthoNormalBasis; public class NormalMapModifier implements Modifier { @@ -18,7 +17,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - normalMap = TextureCache.getTexture(api.resolveTextureFilename(filename), true); + // EP : Made texture cache local to a SunFlow API instance + normalMap = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), true); return normalMap != null; } diff -Nru sunflow/src/org/sunflow/core/photonmap/GlobalPhotonMap.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/photonmap/GlobalPhotonMap.java --- sunflow/src/org/sunflow/core/photonmap/GlobalPhotonMap.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/photonmap/GlobalPhotonMap.java 2010-06-20 22:18:46.000000000 +0200 @@ -260,7 +260,8 @@ t.start(); balance(); t.end(); - UI.taskStop(); + // EP : Replaced task management with interruptions + // UI.taskStop(); UI.printInfo(Module.LIGHT, "Global photon map:"); UI.printInfo(Module.LIGHT, " * Photons stored: %d", storedPhotons); UI.printInfo(Module.LIGHT, " * Photons/estimate: %d", numGather); @@ -328,7 +329,8 @@ curr.data = irr.toRGBE(); temp[i] = curr; } - UI.taskStop(); + // EP : Replaced task management with interruptions + // UI.taskStop(); // resize photon map to only include irradiance photons numGather /= 4; diff -Nru sunflow/src/org/sunflow/core/primitive/CornellBox.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/primitive/CornellBox.java --- sunflow/src/org/sunflow/core/primitive/CornellBox.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/primitive/CornellBox.java 2010-06-20 22:18:46.000000000 +0200 @@ -443,4 +443,14 @@ public Instance createInstance() { return Instance.createTemporary(this, null, this); } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/primitive/Hair.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/primitive/Hair.java --- sunflow/src/org/sunflow/core/primitive/Hair.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/primitive/Hair.java 2010-06-20 22:18:46.000000000 +0200 @@ -258,4 +258,14 @@ public PrimitiveList getBakingPrimitives() { return null; } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/Ray.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/Ray.java --- sunflow/src/org/sunflow/core/Ray.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/Ray.java 2010-06-20 22:18:46.000000000 +0200 @@ -214,4 +214,11 @@ public final void setMax(float t) { tMax = t; } + + // EP : Added transparency management + public void setMinMax(float min, float max) { + tMin = min; + tMax = max; + } + // EP : end of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/renderer/BucketRenderer.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/BucketRenderer.java --- sunflow/src/org/sunflow/core/renderer/BucketRenderer.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/BucketRenderer.java 2010-09-26 12:34:16.000000000 +0200 @@ -157,15 +157,22 @@ renderThreads[i].setPriority(scene.getThreadPriority()); renderThreads[i].start(); } - for (int i = 0; i < renderThreads.length; i++) { - try { - renderThreads[i].join(); - } catch (InterruptedException e) { - UI.printError(Module.BCKT, "Bucket processing thread %d of %d was interrupted", i + 1, renderThreads.length); - } finally { - renderThreads[i].updateStats(); + // EP : Moved InterruptedException out of loop to be able to stop all rendering threads + try { + for (int i = 0; i < renderThreads.length; i++) { + try { + renderThreads[i].join(); + } finally { + renderThreads[i].updateStats(); + } + } + } catch (InterruptedException e) { + for (int i = 0; i < renderThreads.length; i++) { + renderThreads[i].interrupt(); } + UI.printError(Module.BCKT, "Bucket processing was interrupted"); } + // EP : End of modification UI.taskStop(); timer.end(); UI.printInfo(Module.BCKT, "Render time: %s", timer.toString()); @@ -183,7 +190,8 @@ @Override public void run() { - while (true) { + // EP : Check rendering isn't interrupted + while (!isInterrupted()) { int bx, by; synchronized (BucketRenderer.this) { if (bucketCounter >= bucketCoords.length) @@ -194,8 +202,6 @@ bucketCounter += 2; } renderBucket(display, bx, by, threadID, istate); - if (UI.taskCanceled()) - return; } } @@ -251,8 +257,13 @@ } } for (int x = 0; x < sbw - 1; x += maxStepSize) - for (int y = 0; y < sbh - 1; y += maxStepSize) + for (int y = 0; y < sbh - 1; y += maxStepSize) { + // EP : Check rendering isn't interrupted + if (Thread.currentThread().isInterrupted()) { + return; + } refineSamples(samples, sbw, x, y, maxStepSize, thresh, istate); + } if (dumpBuckets) { UI.printInfo(Module.BCKT, "Dumping bucket [%d, %d] to file ...", bx, by); GenericBitmap bitmap = new GenericBitmap(sbw, sbh); @@ -297,7 +308,9 @@ if (Math.abs(dy) > fhs) continue; float f = filter.get(dx, dy); - c.madd(f, samples[s].c); + // EP : Test if color isn't null + if (samples[s].c != null) + c.madd(f, samples[s].c); a += f * samples[s].alpha; weight += f; diff -Nru sunflow/src/org/sunflow/core/renderer/MultipassRenderer.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/MultipassRenderer.java --- sunflow/src/org/sunflow/core/renderer/MultipassRenderer.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/MultipassRenderer.java 2010-06-20 22:18:46.000000000 +0200 @@ -86,15 +86,22 @@ renderThreads[i].setPriority(scene.getThreadPriority()); renderThreads[i].start(); } - for (int i = 0; i < renderThreads.length; i++) { - try { - renderThreads[i].join(); - } catch (InterruptedException e) { - UI.printError(Module.BCKT, "Bucket processing thread %d of %d was interrupted", i + 1, renderThreads.length); - } finally { - renderThreads[i].updateStats(); + // EP : Moved InterruptedException out of loop to be able to stop all rendering threads + try { + for (int i = 0; i < renderThreads.length; i++) { + try { + renderThreads[i].join(); + } finally { + renderThreads[i].updateStats(); + } } + } catch (InterruptedException e) { + for (int i = 0; i < renderThreads.length; i++) { + renderThreads[i].interrupt(); + } + UI.printError(Module.BCKT, "Bucket processing was interrupted"); } + // EP : End of modification UI.taskStop(); timer.end(); UI.printInfo(Module.BCKT, "Render time: %s", timer.toString()); @@ -114,7 +121,8 @@ @Override public void run() { - while (true) { + // EP : Check rendering isn't interrupted or canceled + while (!isInterrupted()) { int bx, by; synchronized (MultipassRenderer.this) { if (bucketCounter >= bucketCoords.length) diff -Nru sunflow/src/org/sunflow/core/renderer/ProgressiveRenderer.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/ProgressiveRenderer.java --- sunflow/src/org/sunflow/core/renderer/ProgressiveRenderer.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/ProgressiveRenderer.java 2010-06-20 22:18:46.000000000 +0200 @@ -58,15 +58,22 @@ renderThreads[i] = new SmallBucketThread(); renderThreads[i].start(); } - for (int i = 0; i < renderThreads.length; i++) { - try { - renderThreads[i].join(); - } catch (InterruptedException e) { - UI.printError(Module.IPR, "Thread %d of %d was interrupted", i + 1, renderThreads.length); - } finally { - renderThreads[i].updateStats(); + // EP : Moved InterruptedException out of loop to be able to stop all rendering threads + try { + for (int i = 0; i < renderThreads.length; i++) { + try { + renderThreads[i].join(); + } finally { + renderThreads[i].updateStats(); + } + } + } catch (InterruptedException e) { + for (int i = 0; i < renderThreads.length; i++) { + renderThreads[i].interrupt(); } + UI.printError(Module.IPR, "Thread was interrupted"); } + // EP : End of modification UI.taskStop(); t.end(); UI.printInfo(Module.IPR, "Rendering time: %s", t.toString()); @@ -78,7 +85,8 @@ @Override public void run() { - while (true) { + // EP : Check rendering isn't interrupted + while (!isInterrupted()) { int n = progressiveRenderNext(istate); synchronized (ProgressiveRenderer.this) { if (counter >= counterMax) @@ -86,8 +94,6 @@ counter += n; UI.taskUpdate(counter); } - if (UI.taskCanceled()) - return; } } diff -Nru sunflow/src/org/sunflow/core/renderer/SimpleRenderer.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/SimpleRenderer.java --- sunflow/src/org/sunflow/core/renderer/SimpleRenderer.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/renderer/SimpleRenderer.java 2010-06-20 22:18:46.000000000 +0200 @@ -41,15 +41,23 @@ renderThreads[i] = new BucketThread(); renderThreads[i].start(); } - for (int i = 0; i < renderThreads.length; i++) { - try { - renderThreads[i].join(); - } catch (InterruptedException e) { - UI.printError(Module.BCKT, "Bucket processing thread %d of %d was interrupted", i + 1, renderThreads.length); - } finally { - renderThreads[i].updateStats(); + // EP : Moved InterruptedException out of loop to be able to stop all rendering threads + try { + for (int i = 0; i < renderThreads.length; i++) { + try { + renderThreads[i].join(); + } finally { + renderThreads[i].updateStats(); + } + } + } catch (InterruptedException e) { + for (int i = 0; i < renderThreads.length; i++) { + renderThreads[i].interrupt(); } + UI.printError(Module.BCKT, "Bucket processing was interrupted"); } + UI.taskStop(); + // EP : End of modification timer.end(); UI.printInfo(Module.BCKT, "Render time: %s", timer.toString()); display.imageEnd(); @@ -60,7 +68,8 @@ @Override public void run() { - while (true) { + // EP : Check rendering isn't interrupted + while (!isInterrupted()) { int bx, by; synchronized (SimpleRenderer.this) { if (bucketCounter >= numBuckets) @@ -90,6 +99,9 @@ for (int y = 0, i = 0; y < bh; y++) { for (int x = 0; x < bw; x++, i++) { + // EP : Check rendering isn't interrupted + if (Thread.currentThread().isInterrupted()) + return; ShadingState state = scene.getRadiance(istate, x0 + x, imageHeight - 1 - (y0 + y), 0.0, 0.0, 0.0, 0, 0, null); bucketRGB[i] = (state != null) ? state.getResult() : Color.BLACK; bucketAlpha[i] = (state != null) ? 1 : 0; diff -Nru sunflow/src/org/sunflow/core/shader/AmbientOcclusionShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/AmbientOcclusionShader.java --- sunflow/src/org/sunflow/core/shader/AmbientOcclusionShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/AmbientOcclusionShader.java 2010-09-28 11:28:50.000000000 +0200 @@ -45,4 +45,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/AnisotropicWardShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/AnisotropicWardShader.java --- sunflow/src/org/sunflow/core/shader/AnisotropicWardShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/AnisotropicWardShader.java 2010-09-28 11:29:26.000000000 +0200 @@ -208,4 +208,14 @@ state.traceReflectionPhoton(r, power); } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/ConstantShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ConstantShader.java --- sunflow/src/org/sunflow/core/shader/ConstantShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ConstantShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -24,4 +24,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/DiffuseShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/DiffuseShader.java --- sunflow/src/org/sunflow/core/shader/DiffuseShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/DiffuseShader.java 2010-09-28 11:29:50.000000000 +0200 @@ -58,4 +58,14 @@ state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/GlassShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/GlassShader.java --- sunflow/src/org/sunflow/core/shader/GlassShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/GlassShader.java 2011-03-13 00:31:10.000000000 +0100 @@ -136,4 +136,14 @@ } } } + + // EP : Added transparency management + public boolean isOpaque() { + return absorptionColor.isWhite(); + } + + public Color getOpacity(ShadingState state) { + return absorptionColor; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/IDShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/IDShader.java --- sunflow/src/org/sunflow/core/shader/IDShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/IDShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -20,4 +20,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/MirrorShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/MirrorShader.java --- sunflow/src/org/sunflow/core/shader/MirrorShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/MirrorShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -59,4 +59,14 @@ dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/NormalShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/NormalShader.java --- sunflow/src/org/sunflow/core/shader/NormalShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/NormalShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -24,4 +24,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/PhongShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/PhongShader.java --- sunflow/src/org/sunflow/core/shader/PhongShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/PhongShader.java 2010-09-28 11:34:54.000000000 +0200 @@ -82,4 +82,14 @@ state.traceReflectionPhoton(new Ray(state.getPoint(), w), power); } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/PrimIDShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/PrimIDShader.java --- sunflow/src/org/sunflow/core/shader/PrimIDShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/PrimIDShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -23,4 +23,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/QuickGrayShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/QuickGrayShader.java --- sunflow/src/org/sunflow/core/shader/QuickGrayShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/QuickGrayShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -56,4 +56,14 @@ state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/ShinyDiffuseShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ShinyDiffuseShader.java --- sunflow/src/org/sunflow/core/shader/ShinyDiffuseShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ShinyDiffuseShader.java 2010-09-29 12:19:42.000000000 +0200 @@ -24,6 +24,12 @@ return true; } + // EP : Added getter to read shininess from subclasses + protected float getShininess() { + return this.refl; + } + // EP : End of modification + public Color getDiffuse(ShadingState state) { return diff; } @@ -90,4 +96,14 @@ state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/SimpleShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/SimpleShader.java --- sunflow/src/org/sunflow/core/shader/SimpleShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/SimpleShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -17,4 +17,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java --- sunflow/src/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -4,7 +4,6 @@ import org.sunflow.core.ParameterList; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; public class TexturedAmbientOcclusionShader extends AmbientOcclusionShader { @@ -18,7 +17,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - tex = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); return tex != null && super.update(pl, api); } diff -Nru sunflow/src/org/sunflow/core/shader/TexturedDiffuseShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedDiffuseShader.java --- sunflow/src/org/sunflow/core/shader/TexturedDiffuseShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedDiffuseShader.java 2010-10-11 12:27:38.000000000 +0200 @@ -2,10 +2,11 @@ import org.sunflow.SunflowAPI; import org.sunflow.core.ParameterList; +import org.sunflow.core.Ray; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; +import org.sunflow.math.Vector3; public class TexturedDiffuseShader extends DiffuseShader { private Texture tex; @@ -18,7 +19,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - tex = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); return tex != null && super.update(pl, api); } @@ -26,4 +28,32 @@ public Color getDiffuse(ShadingState state) { return tex.getPixel(state.getUV().x, state.getUV().y); } + + // EP : Added transparency management + @Override + public Color getRadiance(ShadingState state) { + Color opacity; + if (isOpaque() || (opacity = getOpacity(state)).isWhite()) { + // Pixel is fully opaque + return super.getRadiance(state); + } else { + state.faceforward(); + state.initLightSamples(); + state.initCausticSamples(); + Vector3 refrDir = state.getRay().getDirection(); + Color refraction = state.traceRefraction(new Ray(state.getPoint(), refrDir), 0); + return Color.sub(Color.WHITE, opacity).mul(refraction); + } + } + + @Override + public boolean isOpaque() { + return !(tex.isTransparent()); + } + + @Override + public Color getOpacity(ShadingState state) { + return tex.getOpacity(state.getUV().x, state.getUV().y); + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/TexturedPhongShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedPhongShader.java --- sunflow/src/org/sunflow/core/shader/TexturedPhongShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedPhongShader.java 2010-10-11 13:02:34.000000000 +0200 @@ -2,10 +2,11 @@ import org.sunflow.SunflowAPI; import org.sunflow.core.ParameterList; +import org.sunflow.core.Ray; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; +import org.sunflow.math.Vector3; public class TexturedPhongShader extends PhongShader { private Texture tex; @@ -18,7 +19,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - tex = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); return tex != null && super.update(pl, api); } @@ -26,4 +28,31 @@ public Color getDiffuse(ShadingState state) { return tex.getPixel(state.getUV().x, state.getUV().y); } + + // EP : Added transparency management + @Override + public Color getRadiance(ShadingState state) { + Color opacity; + if (isOpaque() || (opacity = getOpacity(state)).isWhite()) { + return super.getRadiance(state); + } else { + state.faceforward(); + state.initLightSamples(); + state.initCausticSamples(); + Vector3 refrDir = state.getRay().getDirection(); + Color refraction = state.traceRefraction(new Ray(state.getPoint(), refrDir), 0); + return Color.sub(Color.WHITE, opacity).mul(refraction); + } + } + + @Override + public boolean isOpaque() { + return !(tex.isTransparent()); + } + + @Override + public Color getOpacity(ShadingState state) { + return tex.getOpacity(state.getUV().x, state.getUV().y); + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/TexturedShinyDiffuseShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedShinyDiffuseShader.java --- sunflow/src/org/sunflow/core/shader/TexturedShinyDiffuseShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedShinyDiffuseShader.java 2010-10-11 12:51:26.000000000 +0200 @@ -2,10 +2,11 @@ import org.sunflow.SunflowAPI; import org.sunflow.core.ParameterList; +import org.sunflow.core.Ray; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; +import org.sunflow.math.Vector3; public class TexturedShinyDiffuseShader extends ShinyDiffuseShader { private Texture tex; @@ -18,7 +19,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - tex = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); return tex != null && super.update(pl, api); } @@ -26,4 +28,56 @@ public Color getDiffuse(ShadingState state) { return tex.getPixel(state.getUV().x, state.getUV().y); } + + // EP : Added transparency management + @Override + public Color getRadiance(ShadingState state) { + Color opacity; + if (isOpaque() || (opacity = getOpacity(state)).isWhite()) { + // Pixel is fully opaque + return super.getRadiance(state); + } else { + state.faceforward(); + // direct lighting + state.initLightSamples(); + state.initCausticSamples(); + Color d = Color.sub(Color.WHITE, opacity); + Vector3 refrDir = state.getRay().getDirection(); + Color refraction = state.traceRefraction(new Ray(state.getPoint(), refrDir), 0); + d.mul(refraction); + if (!state.includeSpecular() + || opacity.isBlack()) { // No reflection when fully transparent + return d; + } + float cos = state.getCosND(); + float dn = 2 * cos; + Vector3 refDir = new Vector3(); + refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; + refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; + refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; + Ray refRay = new Ray(state.getPoint(), refDir); + // compute Fresnel term + cos = 1 - cos; + float cos2 = cos * cos; + float cos5 = cos2 * cos2 * cos; + + Color ret = Color.white(); + Color r = Color.sub(Color.WHITE, opacity).mul(getShininess()); + ret.sub(r); + ret.mul(cos5); + ret.add(r); + return d.add(ret.mul(state.traceReflection(refRay, 0))); + } + } + + @Override + public boolean isOpaque() { + return !(tex.isTransparent()); + } + + @Override + public Color getOpacity(ShadingState state) { + return tex.getOpacity(state.getUV().x, state.getUV().y); + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/TexturedWardShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedWardShader.java --- sunflow/src/org/sunflow/core/shader/TexturedWardShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/TexturedWardShader.java 2010-09-29 12:21:22.000000000 +0200 @@ -4,7 +4,6 @@ import org.sunflow.core.ParameterList; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; public class TexturedWardShader extends AnisotropicWardShader { @@ -18,7 +17,8 @@ public boolean update(ParameterList pl, SunflowAPI api) { String filename = pl.getString("texture", null); if (filename != null) - tex = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); return tex != null && super.update(pl, api); } @@ -26,4 +26,16 @@ public Color getDiffuse(ShadingState state) { return tex.getPixel(state.getUV().x, state.getUV().y); } + + // EP : Added transparency management + @Override + public boolean isOpaque() { + return !(tex.isTransparent()); + } + + @Override + public Color getOpacity(ShadingState state) { + return tex.getOpacity(state.getUV().x, state.getUV().y); + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/UberShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/UberShader.java --- sunflow/src/org/sunflow/core/shader/UberShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/UberShader.java 2010-10-11 13:02:22.000000000 +0200 @@ -6,7 +6,6 @@ import org.sunflow.core.Shader; import org.sunflow.core.ShadingState; import org.sunflow.core.Texture; -import org.sunflow.core.TextureCache; import org.sunflow.image.Color; import org.sunflow.math.MathUtils; import org.sunflow.math.OrthoNormalBasis; @@ -36,10 +35,12 @@ String filename; filename = pl.getString("diffuse.texture", null); if (filename != null) - diffmap = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + diffmap = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); filename = pl.getString("specular.texture", null); if (filename != null) - specmap = TextureCache.getTexture(api.resolveTextureFilename(filename), false); + // EP : Made texture cache local to a SunFlow API instance + specmap = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false); diffBlend = MathUtils.clamp(pl.getFloat("diffuse.blend", diffBlend), 0, 1); specBlend = MathUtils.clamp(pl.getFloat("specular.blend", diffBlend), 0, 1); glossyness = MathUtils.clamp(pl.getFloat("glossyness", glossyness), 0, 1); @@ -61,30 +62,41 @@ // direct lighting state.initLightSamples(); state.initCausticSamples(); - Color d = getDiffuse(state); - Color lr = state.diffuse(d); - if (!state.includeSpecular()) - return lr; - if (glossyness == 0) { - float cos = state.getCosND(); - float dn = 2 * cos; - Vector3 refDir = new Vector3(); - refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; - refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; - refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; - Ray refRay = new Ray(state.getPoint(), refDir); - // compute Fresnel term - cos = 1 - cos; - float cos2 = cos * cos; - float cos5 = cos2 * cos2 * cos; - Color spec = getSpecular(state); - Color ret = Color.white(); - ret.sub(spec); - ret.mul(cos5); - ret.add(spec); - return lr.add(ret.mul(state.traceReflection(refRay, 0))); - } else - return lr.add(state.specularPhong(getSpecular(state), 2 / glossyness, numSamples)); + // EP : Added transparency management + Color opacity; + if (!isOpaque() && !(opacity = getOpacity(state)).isWhite()) { + Vector3 refrDir = state.getRay().getDirection(); + Color refraction = state.traceRefraction(new Ray(state.getPoint(), refrDir), 0); + return Color.sub(Color.WHITE, opacity).mul(refraction); + } else { + // EP : End of modification + Color d = getDiffuse(state); + Color lr = state.diffuse(d); + if (!state.includeSpecular()) + return lr; + if (glossyness == 0) { + float cos = state.getCosND(); + float dn = 2 * cos; + Vector3 refDir = new Vector3(); + refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; + refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; + refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; + Ray refRay = new Ray(state.getPoint(), refDir); + // compute Fresnel term + cos = 1 - cos; + float cos2 = cos * cos; + float cos5 = cos2 * cos2 * cos; + Color spec = getSpecular(state); + Color ret = Color.white(); + ret.sub(spec); + ret.mul(cos5); + ret.add(spec); + return lr.add(ret.mul(state.traceReflection(refRay, 0))); + } else + return lr.add(state.specularPhong(getSpecular(state), 2 / glossyness, numSamples)); + // EP : Added transparency management + } + // EP : End of modification } public void scatterPhoton(ShadingState state, Color power) { @@ -138,4 +150,14 @@ } } } + + // EP : Added transparency management + public boolean isOpaque() { + return diffmap == null || !(diffmap.isTransparent()); + } + + public Color getOpacity(ShadingState state) { + return diffmap != null ? diffmap.getOpacity(state.getUV().x, state.getUV().y) : Color.WHITE; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/UVShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/UVShader.java --- sunflow/src/org/sunflow/core/shader/UVShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/UVShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -19,4 +19,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/ViewCausticsShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewCausticsShader.java --- sunflow/src/org/sunflow/core/shader/ViewCausticsShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewCausticsShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -25,4 +25,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/ViewGlobalPhotonsShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewGlobalPhotonsShader.java --- sunflow/src/org/sunflow/core/shader/ViewGlobalPhotonsShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewGlobalPhotonsShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -18,4 +18,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/ViewIrradianceShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewIrradianceShader.java --- sunflow/src/org/sunflow/core/shader/ViewIrradianceShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/ViewIrradianceShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -18,4 +18,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/shader/WireframeShader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/WireframeShader.java --- sunflow/src/org/sunflow/core/shader/WireframeShader.java 2011-05-30 19:01:54.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/shader/WireframeShader.java 2010-06-20 22:18:46.000000000 +0200 @@ -73,4 +73,14 @@ public void scatterPhoton(ShadingState state, Color power) { } + + // EP : Added transparency management + public boolean isOpaque() { + return true; + } + + public Color getOpacity(ShadingState state) { + return null; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/Shader.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/Shader.java --- sunflow/src/org/sunflow/core/Shader.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/Shader.java 2010-06-20 22:18:46.000000000 +0200 @@ -26,4 +26,18 @@ * @param power power of the incoming photon. */ public void scatterPhoton(ShadingState state, Color power); + + // EP : Added transparency management + /** + * Returns <code>true</code> if this shader is fully opaque. + * This gives a quick way to find out if a shader needs further processing + * when hit by a shadow ray. + */ + public boolean isOpaque(); + + /** + * Returns how much light is blocked by this shader. + */ + public Color getOpacity(ShadingState state); + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/ShadingState.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/ShadingState.java --- sunflow/src/org/sunflow/core/ShadingState.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/ShadingState.java 2010-11-21 00:14:30.000000000 +0100 @@ -46,9 +46,12 @@ private boolean includeSpecular; private LightSample lightSample; private PhotonStore map; + // EP : Added transparency management + private int shadowDepth; static ShadingState createPhotonState(Ray r, IntersectionState istate, int i, PhotonStore map, LightServer server) { - ShadingState s = new ShadingState(null, istate, r, i, 4); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(null, istate, r, i, 4, false); s.server = server; s.map = map; return s; @@ -56,7 +59,8 @@ } static ShadingState createState(IntersectionState istate, float rx, float ry, float time, Ray r, int i, int d, LightServer server) { - ShadingState s = new ShadingState(null, istate, r, i, d); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(null, istate, r, i, d, false); s.server = server; s.rx = rx; s.ry = ry; @@ -65,40 +69,48 @@ } static ShadingState createDiffuseBounceState(ShadingState previous, Ray r, int i) { - ShadingState s = new ShadingState(previous, previous.istate, r, i, 2); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(previous, previous.istate, r, i, 2, false); s.diffuseDepth++; return s; } static ShadingState createGlossyBounceState(ShadingState previous, Ray r, int i) { - ShadingState s = new ShadingState(previous, previous.istate, r, i, 2); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(previous, previous.istate, r, i, 2, false); s.includeLights = false; - s.includeSpecular = false; - s.reflectionDepth++; + // EP : Set includeSpecular to true to get the reflects + s.includeSpecular = true; + // EP : Very dirty hack to let mirror shader manage more bounces than uber shader + s.reflectionDepth += 4; return s; } static ShadingState createReflectionBounceState(ShadingState previous, Ray r, int i) { - ShadingState s = new ShadingState(previous, previous.istate, r, i, 2); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(previous, previous.istate, r, i, 2, false); s.reflectionDepth++; return s; } static ShadingState createRefractionBounceState(ShadingState previous, Ray r, int i) { - ShadingState s = new ShadingState(previous, previous.istate, r, i, 2); + // EP : Added ignoreHalton parameter + ShadingState s = new ShadingState(previous, previous.istate, r, i, 2, false); s.refractionDepth++; return s; } static ShadingState createFinalGatherState(ShadingState state, Ray r, int i) { - ShadingState finalGatherState = new ShadingState(state, state.istate, r, i, 2); + // EP : Added ignoreHalton parameter + ShadingState finalGatherState = new ShadingState(state, state.istate, r, i, 2, false); finalGatherState.diffuseDepth++; finalGatherState.includeLights = false; finalGatherState.includeSpecular = false; return finalGatherState; } - private ShadingState(ShadingState previous, IntersectionState istate, Ray r, int i, int d) { + // EP : Added ignoreHalton parameter + private ShadingState(ShadingState previous, IntersectionState istate, Ray r, int i, int d, boolean ignoreHalton) { this.r = r; this.istate = istate; this.i = i; @@ -121,6 +133,8 @@ diffuseDepth = previous.diffuseDepth; reflectionDepth = previous.reflectionDepth; refractionDepth = previous.refractionDepth; + // EP : copy shadow depth + shadowDepth = previous.shadowDepth; server = previous.server; map = previous.map; rx = previous.rx; @@ -131,8 +145,12 @@ behind = false; cosND = Float.NaN; includeLights = includeSpecular = true; - qmcD0I = QMC.halton(this.d, this.i); - qmcD1I = QMC.halton(this.d + 1, this.i); + // EP : Ignore Halton values for transparency computing + if (!ignoreHalton) { + qmcD0I = QMC.halton(this.d, this.i); + qmcD1I = QMC.halton(this.d + 1, this.i); + } + // EP : End of modification result = null; bias = 0.001f; } @@ -691,7 +709,8 @@ * @return opacity along the shadow ray */ public final Color traceShadow(Ray r) { - return server.getScene().traceShadow(r, istate); + // EP : Added transparency management + return server.traceShadow(r, this); } /** @@ -926,4 +945,22 @@ throw new UnsupportedOperationException(); } } + + // EP : Added transparency management + static ShadingState createShadowState(ShadingState previous, Ray r) { + ShadingState s = new ShadingState(previous, previous.istate, r, previous.i, previous.d, true); + s.shadowDepth++; + return s; + } + + public final int getShadowDepth() { + return shadowDepth; + } + + public Color traceTransparentShadow(float oldMaxT) { + Ray tr = new Ray(r.ox, r.oy, r.oz, r.dx, r.dy, r.dz); + tr.setMinMax(r.getMax(), oldMaxT); + return traceShadow(tr); + } + // EP : end of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/core/TextureCache.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/TextureCache.java --- sunflow/src/org/sunflow/core/TextureCache.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/TextureCache.java 2010-06-20 22:18:46.000000000 +0200 @@ -10,9 +10,11 @@ * texture might be used more than once in your scene. */ public final class TextureCache { - private static HashMap<String, Texture> textures = new HashMap<String, Texture>(); + // EP : Removed static to enable GC to free Texture memory + private HashMap<String, Texture> textures = new HashMap<String, Texture>(); - private TextureCache() { + // EP : Made texture cache local to SunFlow API + public TextureCache() { } /** @@ -25,7 +27,8 @@ * @return texture object * @see Texture */ - public synchronized static Texture getTexture(String filename, boolean isLinear) { + // EP : Removed static to enable GC to free Texture memory + public synchronized Texture getTexture(String filename, boolean isLinear) { if (textures.containsKey(filename)) { UI.printInfo(Module.TEX, "Using cached copy for file \"%s\" ...", filename); return textures.get(filename); @@ -40,7 +43,8 @@ * Flush all textures from the cache, this will cause them to be reloaded * anew the next time they are accessed. */ - public synchronized static void flush() { + // EP : Removed static to enable GC to free Texture memory + public synchronized void flush() { UI.printInfo(Module.TEX, "Flushing texture cache"); textures.clear(); } diff -Nru sunflow/src/org/sunflow/core/Texture.java sunflow-0.07.3g-src-diff/src/org/sunflow/core/Texture.java --- sunflow/src/org/sunflow/core/Texture.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/core/Texture.java 2010-09-28 18:38:56.000000000 +0200 @@ -1,6 +1,8 @@ package org.sunflow.core; import java.io.IOException; +import java.io.InputStream; +import java.net.URL; import org.sunflow.PluginRegistry; import org.sunflow.image.Bitmap; @@ -23,6 +25,8 @@ private boolean isLinear; private Bitmap bitmap; private int loaded; + // EP : Added bitmap transparency support + private boolean isTransparent; /** * Creates a new texture from the specfied file. @@ -43,11 +47,38 @@ try { UI.printInfo(Module.TEX, "Reading texture bitmap from: \"%s\" ...", filename); BitmapReader reader = PluginRegistry.bitmapReaderPlugins.createObject(extension); + // EP : Tolerate no extension in URLs + if (reader == null) { + try { + // Choose a reader depending on the magic number of the file + URL url = new URL(filename); + InputStream in = url.openStream(); + int firstByte = in.read(); + int secondByte = in.read(); + in.close(); + reader = firstByte == 0xFF && secondByte == 0xD8 + ? PluginRegistry.bitmapReaderPlugins.createObject("jpg") + : PluginRegistry.bitmapReaderPlugins.createObject("png"); + } catch (IOException ex) { + // Don't try to search an other reader + } + } + // EP : End of modification if (reader != null) { bitmap = reader.load(filename, isLinear); if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0) bitmap = null; } + // EP : Check transparency + for (int x = 0; x < bitmap.getWidth(); x++) { + for (int y = 0; y < bitmap.getHeight(); y++) { + if (bitmap.readAlpha(x, y) < 1) { + this.isTransparent = true; + break; + } + } + } + // EP : End of modification if (bitmap == null) { UI.printError(Module.TEX, "Bitmap reading failed"); bitmap = new BitmapBlack(); @@ -105,7 +136,51 @@ c.madd(k11, c11); return c; } - + + // EP : Added bitmap transparency support + public Color getOpacity(float x, float y) { + Bitmap bitmap = getBitmap(); + x = MathUtils.frac(x); + y = MathUtils.frac(y); + float dx = x * (bitmap.getWidth() - 1); + float dy = y * (bitmap.getHeight() - 1); + int ix0 = (int) dx; + int iy0 = (int) dy; + int ix1 = (ix0 + 1) % bitmap.getWidth(); + int iy1 = (iy0 + 1) % bitmap.getHeight(); + float u = dx - ix0; + float v = dy - iy0; + u = u * u * (3.0f - (2.0f * u)); + v = v * v * (3.0f - (2.0f * v)); + float k00 = (1.0f - u) * (1.0f - v); + float a00 = bitmap.readAlpha(ix0, iy0); + float k01 = (1.0f - u) * v; + float a01 = bitmap.readAlpha(ix0, iy1); + float k10 = u * (1.0f - v); + float a10 = bitmap.readAlpha(ix1, iy0); + float k11 = u * v; + float a11 = bitmap.readAlpha(ix1, iy1); + float transparency = k00 * a00 + k01 * a01 + k10 * a10 + k11 * a11; + if (transparency <= 0.9999) { + Color c00 = bitmap.readColor(ix0, iy0); + Color c01 = bitmap.readColor(ix0, iy1); + Color c10 = bitmap.readColor(ix1, iy0); + Color c11 = bitmap.readColor(ix1, iy1); + Color c = Color.mul(k00, c00); + c.madd(k01, c01); + c.madd(k10, c10); + c.madd(k11, c11); + return c.opposite().mul(transparency); + } else { + return Color.WHITE; + } + } + + public boolean isTransparent() { + return this.isTransparent; + } + // EP : End of modification + public Vector3 getNormal(float x, float y, OrthoNormalBasis basis) { float[] rgb = getPixel(x, y).getRGB(); return basis.transform(new Vector3(2 * rgb[0] - 1, 2 * rgb[1] - 1, 2 * rgb[2] - 1)).normalize(); diff -Nru sunflow/src/org/sunflow/image/Color.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/Color.java --- sunflow/src/org/sunflow/image/Color.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/Color.java 2010-09-29 10:28:50.000000000 +0200 @@ -116,6 +116,12 @@ return r <= 0 && g <= 0 && b <= 0; } + // EP : Added to manage white colors + public boolean isWhite() { + return r >= 1 && g >= 1 && b >= 1; + } + // EP : End of modification + public final float getLuminance() { return (0.2989f * r) + (0.5866f * g) + (0.1145f * b); } diff -Nru sunflow/src/org/sunflow/image/readers/BMPBitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/BMPBitmapReader.java --- sunflow/src/org/sunflow/image/readers/BMPBitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/BMPBitmapReader.java 2010-06-20 22:18:46.000000000 +0200 @@ -1,8 +1,11 @@ package org.sunflow.image.readers; import java.awt.image.BufferedImage; -import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import javax.imageio.ImageIO; @@ -13,8 +16,25 @@ public class BMPBitmapReader implements BitmapReader { public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - // regular image, load using Java api - ignore alpha channel - BufferedImage bi = ImageIO.read(new File(filename)); + // EP : Try to read filename as an URL or as a file + InputStream f; + try { + // Let's try first to read filename as an URL + f = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + f = new FileInputStream(filename); + } + + BufferedImage bi; + try { + // regular image, load using Java api - ignore alpha channel + bi = ImageIO.read(f); + } finally { + f.close(); + } + // EP : End of modification + int width = bi.getWidth(); int height = bi.getHeight(); byte[] pixels = new byte[3 * width * height]; diff -Nru sunflow/src/org/sunflow/image/readers/HDRBitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/HDRBitmapReader.java --- sunflow/src/org/sunflow/image/readers/HDRBitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/HDRBitmapReader.java 2010-06-20 22:18:46.000000000 +0200 @@ -4,6 +4,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import org.sunflow.image.Bitmap; import org.sunflow.image.BitmapReader; @@ -11,8 +13,19 @@ public class HDRBitmapReader implements BitmapReader { public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - // load radiance rgbe file - InputStream f = new BufferedInputStream(new FileInputStream(filename)); + // EP : Try to read filename as an URL or as a file + InputStream f; + try { + // Let's try first to read filename as an URL + f = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + f = new FileInputStream(filename); + } + + f = new BufferedInputStream(f); + // End of modification + // parse header boolean parseWidth = false, parseHeight = false; int width = 0, height = 0; diff -Nru sunflow/src/org/sunflow/image/readers/IGIBitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/IGIBitmapReader.java --- sunflow/src/org/sunflow/image/readers/IGIBitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/IGIBitmapReader.java 2010-06-20 22:18:46.000000000 +0200 @@ -4,6 +4,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import org.sunflow.image.Bitmap; import org.sunflow.image.BitmapReader; @@ -15,7 +17,19 @@ */ public class IGIBitmapReader implements BitmapReader { public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - InputStream stream = new BufferedInputStream(new FileInputStream(filename)); + // EP : Try to read filename as an URL or as a file + InputStream stream; + try { + // Let's try first to read filename as an URL + stream = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + stream = new FileInputStream(filename); + } + + stream = new BufferedInputStream(stream); + // End of modification + // read header int magic = read32i(stream); int version = read32i(stream); diff -Nru sunflow/src/org/sunflow/image/readers/JPGBitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/JPGBitmapReader.java --- sunflow/src/org/sunflow/image/readers/JPGBitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/JPGBitmapReader.java 2010-10-18 23:51:52.000000000 +0200 @@ -1,8 +1,13 @@ package org.sunflow.image.readers; +import java.awt.Graphics2D; +import java.awt.Transparency; import java.awt.image.BufferedImage; -import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import javax.imageio.ImageIO; @@ -13,14 +18,47 @@ public class JPGBitmapReader implements BitmapReader { public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - // regular image, load using Java api - ignore alpha channel - BufferedImage bi = ImageIO.read(new File(filename)); + // EP : Try to read filename as an URL or as a file + InputStream f; + try { + // Let's try first to read filename as an URL + f = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + f = new FileInputStream(filename); + } + + BufferedImage bi; + try { + // regular image, load using Java api - ignore alpha channel + bi = ImageIO.read(f); + } finally { + f.close(); + } + + if (bi.getType() != BufferedImage.TYPE_INT_RGB + && bi.getType() != BufferedImage.TYPE_INT_ARGB) { + // Transform as TYPE_INT_ARGB or TYPE_INT_RGB (much faster than calling image.getRGB()) + BufferedImage tmp = new BufferedImage(bi.getWidth(), bi.getHeight(), + bi.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB); + Graphics2D g = (Graphics2D)tmp.getGraphics(); + g.drawImage(bi, null, 0, 0); + g.dispose(); + bi = tmp; + } + // Retrieve image bits + int [] imageBits = (int [])bi.getRaster().getDataElements(0, 0, bi.getWidth(), bi.getHeight(), null); + // EP : End of modification + int width = bi.getWidth(); int height = bi.getHeight(); byte[] pixels = new byte[3 * width * height]; for (int y = 0, index = 0; y < height; y++) { for (int x = 0; x < width; x++, index += 3) { - int argb = bi.getRGB(x, height - 1 - y); + // EP : Retrieved image data with raster data + // int argb = bi.getRGB(x, height - 1 - y); + int argb = imageBits [x + (height - 1 - y) * width]; + // EP : End of modification pixels[index + 0] = (byte) (argb >> 16); pixels[index + 1] = (byte) (argb >> 8); pixels[index + 2] = (byte) argb; diff -Nru sunflow/src/org/sunflow/image/readers/PNGBitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/PNGBitmapReader.java --- sunflow/src/org/sunflow/image/readers/PNGBitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/PNGBitmapReader.java 2011-01-16 21:27:56.000000000 +0100 @@ -1,8 +1,13 @@ package org.sunflow.image.readers; +import java.awt.Graphics2D; +import java.awt.Transparency; import java.awt.image.BufferedImage; -import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import javax.imageio.ImageIO; @@ -13,18 +18,54 @@ public class PNGBitmapReader implements BitmapReader { public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - // regular image, load using Java api - BufferedImage bi = ImageIO.read(new File(filename)); + // EP : Try to read filename as an URL or as a file + InputStream f; + try { + // Let's try first to read filename as an URL + f = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + f = new FileInputStream(filename); + } + + BufferedImage bi; + try { + // regular image, load using Java api + bi = ImageIO.read(f); + } finally { + f.close(); + } + + boolean opaque = bi.getTransparency() == Transparency.OPAQUE; + if (bi.getType() != BufferedImage.TYPE_INT_RGB + && bi.getType() != BufferedImage.TYPE_INT_ARGB) { + // Transform as TYPE_INT_ARGB or TYPE_INT_RGB (much faster than calling image.getRGB()) + BufferedImage tmp = new BufferedImage(bi.getWidth(), bi.getHeight(), + opaque ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB); + Graphics2D g = (Graphics2D)tmp.getGraphics(); + g.drawImage(bi, null, 0, 0); + g.dispose(); + bi = tmp; + } + // Retrieve image bits + int [] imageBits = (int [])bi.getRaster().getDataElements(0, 0, bi.getWidth(), bi.getHeight(), null); + // EP : End of modification + int width = bi.getWidth(); int height = bi.getHeight(); byte[] pixels = new byte[4 * width * height]; for (int y = 0, index = 0; y < height; y++) { for (int x = 0; x < width; x++, index += 4) { - int argb = bi.getRGB(x, height - 1 - y); + // EP : Retrieved image data with raster data + // int argb = bi.getRGB(x, height - 1 - y); + int argb = imageBits [x + (height - 1 - y) * width]; + // EP : End of modification pixels[index + 0] = (byte) (argb >> 16); pixels[index + 1] = (byte) (argb >> 8); pixels[index + 2] = (byte) argb; - pixels[index + 3] = (byte) (argb >> 24); + // EP : Added opaque transparency + pixels[index + 3] = opaque ? (byte)0xFF : (byte) (argb >> 24); + // EP : End of modification } } if (!isLinear) { diff -Nru sunflow/src/org/sunflow/image/readers/TGABitmapReader.java sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/TGABitmapReader.java --- sunflow/src/org/sunflow/image/readers/TGABitmapReader.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/image/readers/TGABitmapReader.java 2010-06-20 22:18:46.000000000 +0200 @@ -4,6 +4,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import org.sunflow.image.Bitmap; import org.sunflow.image.BitmapReader; @@ -16,7 +18,19 @@ private static final int[] CHANNEL_INDEX = { 2, 1, 0, 3 }; public Bitmap load(String filename, boolean isLinear) throws IOException, BitmapFormatException { - InputStream f = new BufferedInputStream(new FileInputStream(filename)); + // EP : Try to read filename as an URL or as a file + InputStream f; + try { + // Let's try first to read filename as an URL + f = new URL(filename).openStream(); + } catch (MalformedURLException ex) { + // Let's try to read filename as a file + f = new FileInputStream(filename); + } + + f = new BufferedInputStream(f); + // End of modification + byte[] read = new byte[4]; // read header diff -Nru sunflow/src/org/sunflow/PluginRegistry.java sunflow-0.07.3g-src-diff/src/org/sunflow/PluginRegistry.java --- sunflow/src/org/sunflow/PluginRegistry.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/PluginRegistry.java 2010-06-20 22:18:46.000000000 +0200 @@ -51,12 +51,12 @@ import org.sunflow.core.modifiers.BumpMappingModifier; import org.sunflow.core.modifiers.NormalMapModifier; import org.sunflow.core.modifiers.PerlinModifier; -import org.sunflow.core.parser.RA2Parser; -import org.sunflow.core.parser.RA3Parser; -import org.sunflow.core.parser.SCAsciiParser; -import org.sunflow.core.parser.SCBinaryParser; -import org.sunflow.core.parser.SCParser; -import org.sunflow.core.parser.ShaveRibParser; +//import org.sunflow.core.parser.RA2Parser; +//import org.sunflow.core.parser.RA3Parser; +//import org.sunflow.core.parser.SCAsciiParser; +//import org.sunflow.core.parser.SCBinaryParser; +//import org.sunflow.core.parser.SCParser; +//import org.sunflow.core.parser.ShaveRibParser; import org.sunflow.core.photonmap.CausticPhotonMap; import org.sunflow.core.photonmap.GlobalPhotonMap; import org.sunflow.core.photonmap.GridPhotonMap; @@ -291,15 +291,16 @@ imageSamplerPlugins.registerPlugin("multipass", MultipassRenderer.class); } - static { - // parsers - parserPlugins.registerPlugin("sc", SCParser.class); - parserPlugins.registerPlugin("sca", SCAsciiParser.class); - parserPlugins.registerPlugin("scb", SCBinaryParser.class); - parserPlugins.registerPlugin("rib", ShaveRibParser.class); - parserPlugins.registerPlugin("ra2", RA2Parser.class); - parserPlugins.registerPlugin("ra3", RA3Parser.class); - } +// EP : Don't need parsers +// static { +// // parsers +// parserPlugins.registerPlugin("sc", SCParser.class); +// parserPlugins.registerPlugin("sca", SCAsciiParser.class); +// parserPlugins.registerPlugin("scb", SCBinaryParser.class); +// parserPlugins.registerPlugin("rib", ShaveRibParser.class); +// parserPlugins.registerPlugin("ra2", RA2Parser.class); +// parserPlugins.registerPlugin("ra3", RA3Parser.class); +// } static { // bitmap readers @@ -309,6 +310,8 @@ bitmapReaderPlugins.registerPlugin("jpg", JPGBitmapReader.class); bitmapReaderPlugins.registerPlugin("bmp", BMPBitmapReader.class); bitmapReaderPlugins.registerPlugin("igi", IGIBitmapReader.class); + // EP : Added extension jpeg + bitmapReaderPlugins.registerPlugin("jpeg", JPGBitmapReader.class); } static { diff -Nru sunflow/src/org/sunflow/SunflowAPI.java sunflow-0.07.3g-src-diff/src/org/sunflow/SunflowAPI.java --- sunflow/src/org/sunflow/SunflowAPI.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/SunflowAPI.java 2010-06-20 22:18:46.000000000 +0200 @@ -1,16 +1,8 @@ package org.sunflow; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.StringReader; import java.util.Locale; -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.core.Camera; import org.sunflow.core.CameraLens; import org.sunflow.core.Display; @@ -26,6 +18,7 @@ import org.sunflow.core.SceneParser; import org.sunflow.core.Shader; import org.sunflow.core.Tesselatable; +import org.sunflow.core.TextureCache; import org.sunflow.core.ParameterList.InterpolationType; import org.sunflow.image.ColorFactory; import org.sunflow.image.ColorFactory.ColorSpecificationException; @@ -36,7 +29,6 @@ import org.sunflow.math.Vector3; import org.sunflow.system.FileUtils; import org.sunflow.system.SearchPath; -import org.sunflow.system.Timer; import org.sunflow.system.UI; import org.sunflow.system.UI.Module; @@ -565,51 +557,53 @@ * @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()); - // allow relative paths - 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.currentFrame(frameNumber); - api.build(); - t.end(); - UI.printInfo(Module.API, "Build script time: %s", t.toString()); - } else { - api = new SunflowAPI(); - api = api.include(filename) ? api : null; - } - return api; +// EP : Don't need parser +// 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()); +// // allow relative paths +// 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.currentFrame(frameNumber); +// api.build(); +// t.end(); +// UI.printInfo(Module.API, "Build script time: %s", t.toString()); +// } else { +// api = new SunflowAPI(); +// api = api.include(filename) ? api : null; +// } +// return api; + throw new UnsupportedOperationException("Removed parser support from SunFlow"); } /** @@ -620,35 +614,37 @@ * @return <code>true</code> upon success, <code>false</code> otherwise */ public static boolean translate(String filename, String outputFilename) { - FileSunflowAPI api = null; - try { - if (outputFilename.endsWith(".sca")) - api = new AsciiFileSunflowAPI(outputFilename); - else if (outputFilename.endsWith(".scb")) - api = new BinaryFileSunflowAPI(outputFilename); - else { - UI.printError(Module.API, "Unable to determine output filetype: \"%s\"", outputFilename); - return false; - } - } catch (IOException e) { - UI.printError(Module.API, "Unable to create output file - %s", e.getMessage()); - return false; - } - String extension = filename.substring(filename.lastIndexOf('.') + 1); - SceneParser parser = PluginRegistry.parserPlugins.createObject(extension); - if (parser == null) { - UI.printError(Module.API, "Unable to find a suitable parser for: \"%s\"", filename); - return false; - } - try { - return parser.parse(filename, api); - } catch (RuntimeException e) { - e.printStackTrace(); - UI.printError(Module.API, "Error occured during translation: %s", e.getMessage()); - return false; - } finally { - api.close(); - } +// EP : Don't need parser +// FileSunflowAPI api = null; +// try { +// if (outputFilename.endsWith(".sca")) +// api = new AsciiFileSunflowAPI(outputFilename); +// else if (outputFilename.endsWith(".scb")) +// api = new BinaryFileSunflowAPI(outputFilename); +// else { +// UI.printError(Module.API, "Unable to determine output filetype: \"%s\"", outputFilename); +// return false; +// } +// } catch (IOException e) { +// UI.printError(Module.API, "Unable to create output file - %s", e.getMessage()); +// return false; +// } +// String extension = filename.substring(filename.lastIndexOf('.') + 1); +// SceneParser parser = PluginRegistry.parserPlugins.createObject(extension); +// if (parser == null) { +// UI.printError(Module.API, "Unable to find a suitable parser for: \"%s\"", filename); +// return false; +// } +// try { +// return parser.parse(filename, api); +// } catch (RuntimeException e) { +// e.printStackTrace(); +// UI.printError(Module.API, "Error occured during translation: %s", e.getMessage()); +// return false; +// } finally { +// api.close(); +// } + throw new UnsupportedOperationException("Removed parser support from SunFlow"); } /** @@ -661,26 +657,28 @@ * 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; - } +// EP : Don't need parser +// 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; +// } + throw new UnsupportedOperationException("Removed parser support from SunFlow"); } /** @@ -697,4 +695,12 @@ public void currentFrame(int currentFrame) { this.currentFrame = currentFrame; } + + // EP : Made texture cache local to a SunFlow API instance + private TextureCache textureCache = new TextureCache(); + + public TextureCache getTextureCache() { + return this.textureCache; + } + // EP : End of modification } \ Manca newline alla fine del file diff -Nru sunflow/src/org/sunflow/system/ImagePanel.java sunflow-0.07.3g-src-diff/src/org/sunflow/system/ImagePanel.java --- sunflow/src/org/sunflow/system/ImagePanel.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/system/ImagePanel.java 2010-06-20 22:18:48.000000000 +0200 @@ -4,7 +4,6 @@ import java.awt.Graphics; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; -import java.awt.event.MouseWheelEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -78,10 +77,11 @@ mouseDragged(e); } - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - zoom(-20 * e.getWheelRotation(), 0); - } +// EP : Support Java 1.5 +// @Override +// public void mouseWheelMoved(MouseWheelEvent e) { +// zoom(-20 * e.getWheelRotation(), 0); +// } } public ImagePanel() { @@ -92,7 +92,8 @@ ScrollZoomListener listener = new ScrollZoomListener(); addMouseListener(listener); addMouseMotionListener(listener); - addMouseWheelListener(listener); +// EP : Support Java 1.5 +// addMouseWheelListener(listener); } public void save(String filename) { diff -Nru sunflow/src/org/sunflow/system/Plugins.java sunflow-0.07.3g-src-diff/src/org/sunflow/system/Plugins.java --- sunflow/src/org/sunflow/system/Plugins.java 2011-05-30 19:01:53.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/org/sunflow/system/Plugins.java 2010-06-20 22:18:48.000000000 +0200 @@ -1,9 +1,5 @@ package org.sunflow.system; -import org.codehaus.janino.ClassBodyEvaluator; -import org.codehaus.janino.CompileException; -import org.codehaus.janino.Parser.ParseException; -import org.codehaus.janino.Scanner.ScanException; import org.sunflow.system.UI.Module; import org.sunflow.util.FastHashMap; @@ -98,25 +94,27 @@ */ @SuppressWarnings("unchecked") public boolean registerPlugin(String name, String sourceCode) { - try { - ClassBodyEvaluator cbe = new ClassBodyEvaluator(); - cbe.setClassName(name); - if (baseClass.isInterface()) - cbe.setImplementedTypes(new Class[] { baseClass }); - else - cbe.setExtendedType(baseClass); - cbe.cook(sourceCode); - return registerPlugin(name, cbe.getClazz()); - } catch (CompileException e) { - UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); - return false; - } catch (ParseException e) { - UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); - return false; - } catch (ScanException e) { - UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); - return false; - } +// EP : Don't need parser +// try { +// ClassBodyEvaluator cbe = new ClassBodyEvaluator(); +// cbe.setClassName(name); +// if (baseClass.isInterface()) +// cbe.setImplementedTypes(new Class[] { baseClass }); +// else +// cbe.setExtendedType(baseClass); +// cbe.cook(sourceCode); +// return registerPlugin(name, cbe.getClazz()); +// } catch (CompileException e) { +// UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); +// return false; +// } catch (ParseException e) { +// UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); +// return false; +// } catch (ScanException e) { +// UI.printError(Module.API, "Plugin \"%s\" could not be declared - %s", name, e.getLocalizedMessage()); +// return false; +// } + return false; } /** diff -Nru sunflow/src/SunflowGUI.java sunflow-0.07.3g-src-diff/src/SunflowGUI.java --- sunflow/src/SunflowGUI.java 2011-05-30 19:01:55.000000000 +0200 +++ sunflow-0.07.3g-src-diff/src/SunflowGUI.java 2010-09-29 12:12:38.000000000 +0200 @@ -43,7 +43,6 @@ import org.sunflow.RealtimeBenchmark; import org.sunflow.SunflowAPI; import org.sunflow.core.Display; -import org.sunflow.core.TextureCache; import org.sunflow.core.accel.KDTree; import org.sunflow.core.display.FileDisplay; import org.sunflow.core.display.FrameDisplay; @@ -52,9 +51,9 @@ import org.sunflow.system.ImagePanel; import org.sunflow.system.Timer; import org.sunflow.system.UI; -import org.sunflow.system.UserInterface; import org.sunflow.system.UI.Module; import org.sunflow.system.UI.PrintLevel; +import org.sunflow.system.UserInterface; @SuppressWarnings("serial") public class SunflowGUI extends javax.swing.JFrame implements UserInterface { @@ -1069,7 +1068,8 @@ } private void textureCacheClearMenuItemActionPerformed(ActionEvent evt) { - TextureCache.flush(); + // EP : Made texture cache local to SunFlow API + api.getTextureCache().flush(); } private void smallTrianglesMenuItemActionPerformed(ActionEvent evt) {