/** Company: Shout3D LLC Project: Shout3D 2.0 Sample Code Class: IncrementalTexture Date: July 12, 2000 Description: A subclass of PixelBasedTexture that reads in one url after the other until the last is loaded (C) Copyright Shout3D LLC. - 1997-2001 - All rights reserved */ package custom_nodes; import shout3d.core.*; import shout3d.*; import java.awt.Graphics; /** * IncrementalTexture * * A subclass of PixelBasedTexture that reads in one url after another until * the last is loaded. * * @author Paul Isaacs */ public class IncrementalTexture extends PixelBasedTexture implements FieldObserver, ResourceObserver, RenderObserver { final public StringArrayField allUrls = new StringArrayField(this, "allUrls", Field.ANY, null); /** * Constructs a default IncrementalTexture node. */ public IncrementalTexture() { allUrls.addFieldObserver(this,null); } public void finalize() throws Throwable { allUrls.removeFieldObserver(this); if (getViewer()!=null) { getViewer().getResourceListener().removeResourceObserver(this); getViewer().getRenderer().removeRenderObserver(this); } // Must call this or super classes will not properly finalize. super.finalize(); } /** * Override this to add a resource observer to the viewer. */ public void setViewer(Shout3DViewer v) { super.setViewer(v); if (getViewer()!=null) { getViewer().getResourceListener().addResourceObserver(this,null); getViewer().getRenderer().addRenderObserver(this,null); } } public void onFieldChange(Field theField, Object userData) { // When the allUrls field changes, kick off the successive loading // of each of the urls listed in that field. if (theField == allUrls) { startLoadingUrl(0); } } int curLoadingUrlIndex = 0; String curLoadingUrl = null; ImageTexture myImageTexture = null; /** * Commences loading of the i'th url in the allUrls field. * If i is greater than the number of urls in the field, does nothing. */ void startLoadingUrl(int i) { if (allUrls.getValue() != null && allUrls.getValue().length > i) { // Initialize myImageTexture if first time. if (myImageTexture == null) { myImageTexture = new ImageTexture(); // Important, or the image texture won't be able to load images myImageTexture.setViewer(getViewer()); // This will make the texture start loading as soon as the url field is set. // Important, since otherwise an ImageTexture waits until it's rendered in a Shape, // and we're storing this node "on the side." myImageTexture.loadASAP.setValue(true); } // get myImageTexture to start loading // When it's done, this node's onLoadDone() method will be called. curLoadingUrlIndex = i; curLoadingUrl = allUrls.getValue()[i]; myImageTexture.url.setValue(new String[] { curLoadingUrl }); } } byte[][] urlsRed, urlsGreen, urlsBlue, urlsAlpha; int urlsWidth, urlsHeight; boolean waitingToSetPixels = false; public void onLoadDone(String nameOfResource, boolean success, Object userData) { // Is this the resource we're waiting for? if ( isDesiredResource(nameOfResource, curLoadingUrl) ) { // Save the pixels from myImageTexture (which kindly loaded them for us). // The second arguments of false mean to return a reference, not a copy. urlsRed = myImageTexture.getChannel(RED, false); urlsGreen = myImageTexture.getChannel(GREEN, false); urlsBlue = myImageTexture.getChannel(BLUE, false); urlsAlpha = myImageTexture.getChannel(ALPHA, false); urlsWidth = myImageTexture.getWidth(); urlsHeight = myImageTexture.getHeight(); // Set flag to transfer these saved pixels to our own before the next render. // Don't do this right now, because we might be in mid-render and so we could // cause exceptions or at least funky rendering. waitingToSetPixels = true; } } boolean isDesiredResource(String nameOfResource, String nameToMatch) { // Get the part of "nameToMatch" without any directory path prefixing it. // Find the last slash. Check forward and backward, since either could turn up in file. int lastSlashInd = nameToMatch.lastIndexOf('/'); if (lastSlashInd == -1) lastSlashInd = nameToMatch.lastIndexOf('\\'); String justFileName; if (lastSlashInd == -1) justFileName = nameToMatch; // No slash in name else justFileName = nameToMatch.substring(lastSlashInd+1); // Start with character after slash return ( nameOfResource.indexOf(justFileName) != -1); } /** * If it's time, set our pixels from the most recently saved ones. */ public void onPreRender(Renderer r, Object userData) { if (waitingToSetPixels == true) { setCustomPixels(urlsWidth, urlsHeight, urlsRed, urlsGreen, urlsBlue, urlsAlpha); waitingToSetPixels = false; // Start loading the next url in the allUrls field. curLoadingUrlIndex++; startLoadingUrl(curLoadingUrlIndex); } } /** * Do nothing here. */ public void onPostRender(Renderer r, Object userData){ } }