📄 animatedplanetshelper.java
字号:
package net.sf.jawp.gui.client.semi3d;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import net.sf.jawp.api.domain.Planet;
import net.sf.jawp.gui.client.j3d.Scene;
import net.sf.jawp.j3d.texture.TextureGroup;
import net.sf.jawp.j3d.texture.TextureManager;
/**
* Singleton for rotating planets images.
*
* @author jarek
* @version $Revision$
*
*/
public class AnimatedPlanetsHelper
{
public static final int STEPS = 64;
public static final int WIDTH = 100;
public static final int HEIGHT = 100;
private final TextureGroup textureGroup;
private final HashMap<String, PlanetAnimation> animations = new HashMap<String, PlanetAnimation>();
private final Executor executor;
private AnimatedPlanetsHelper()
{
TextureGroup txm = null;
try
{
final TextureManager mgr = new TextureManager(Scene.class
.getResourceAsStream("textures.xml"));
txm = mgr.getGroup("planets");
}
catch (final Exception e)
{
e.printStackTrace(System.err);
txm = null;
}
textureGroup = txm;
this.executor = Executors.newSingleThreadExecutor( new LowPrioThreadFactory());
}
public static AnimatedPlanetsHelper getInstance()
{
return AnimatedPlanetsHelperHolder.INSTANCE;
}
public final Image getImage(final Planet planet, final int step)
{
final String id = chooseTextureIdForPlanet(planet);
final PlanetAnimation anim = getPlanetAnimation(id);
return anim.getImage(step);
}
private PlanetAnimation getPlanetAnimation(final String id)
{
synchronized (this.animations)
{
final PlanetAnimation anim = this.animations.get(id);
if (anim == null)
{
return createPlanetAnimation(id);
}
else
{
return anim;
}
}
}
private PlanetAnimation createPlanetAnimation(final String id)
{
final PlanetAnimation result = new PlanetAnimation(id);
this.animations.put(id, result);
// add tasks
startTasks(result);
return result;
}
private void startTasks(final PlanetAnimation result)
{
for (int i = 0; i < STEPS; ++i)
{
this.executor.execute(new AnimationStepTask(result, i));
}
}
private static class LowPrioThreadFactory implements ThreadFactory
{
public final Thread newThread(final Runnable runnable)
{
final Thread result = new Thread ( runnable);
result.setPriority( Thread.MIN_PRIORITY);
return result;
}
}
private static class AnimationStepTask implements Runnable
{
private final int step;
private final PlanetAnimation anim;
public AnimationStepTask(final PlanetAnimation anim, final int step)
{
this.step = step;
this.anim = anim;
}
public void run()
{
// System.out.println("gonna create animation step:" + step);
final Image img = renderImage(anim.getTextureImage(), step);
if (img != null)
{
anim.putStep(img);
}
}
}
private String chooseTextureIdForPlanet(final Planet planet)
{
int sum = 0;
final String planetName = planet.getName();
for (int i = 0; i < planetName.length(); ++i)
{
sum += planetName.charAt(i);
}
return String.valueOf(sum % textureGroup.getCount());
}
private class PlanetAnimation
{
/**
* stored teture
*/
private Image textureImage;
private final String textId;
private final ArrayList<Image> steps = new ArrayList<Image>(STEPS);
public PlanetAnimation(final String id)
{
this.textId = id;
}
public final void putStep(final Image img)
{
synchronized (steps)
{
steps.add(img);
}
}
public final Image getImage(final int pos)
{
int size = 0;
synchronized (this.steps)
{
size = this.steps.size();
}
if (size == 0)
{
return getTextureImage();
}
synchronized (this.steps)
{
return this.steps.get(Math.min(size - 1, pos));
}
}
private synchronized Image getTextureImage()
{
if (this.textureImage == null)
{
this.textureImage = loadTexture();
}
return this.textureImage;
}
private Image loadTexture()
{
final Image img = textureGroup.getImage(this.textId);
final BufferedImage buf = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_3BYTE_BGR);
buf.getGraphics().drawImage(
img.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_SMOOTH),
0, 0, null);
return buf;
}
}
private static class AnimatedPlanetsHelperHolder
{
private static final AnimatedPlanetsHelper INSTANCE = new AnimatedPlanetsHelper();
}
private static Image renderImage(final Image texture, final int step)
{
Image result = null;
try
{
final int[] imageData = new int[WIDTH * HEIGHT];
final MemoryImageSource source = new MemoryImageSource(WIDTH, HEIGHT,
imageData, 0, WIDTH);
source.setAnimated(true);
source.setFullBufferUpdates(true);
result = Toolkit.getDefaultToolkit().createImage(source);
final float shift = (float) step / (float) STEPS;
final Texture textureImg = new ImageTexture(texture, texture
.getWidth(null), texture.getHeight(null), shift);
final Light light = new DirectionalLight(.6, .4, .6);
final Obj obj = new Sphere(WIDTH, HEIGHT * 1 / 2, textureImg, light);
final int width = WIDTH;
final int height = HEIGHT;
final int sup = 2;
final double supInv = 1.0 / sup;
for (int j = 0; j < height; ++j)
{
for (int i = 0; i < width; ++i)
{
final RGB pixel = new RGB(0.0, 0.0, 0.0);
for (int k = 0; k < sup; ++k)
{
for (int l = 0; l < sup; ++l)
{
final Vec ray = new Vec((i * 2. - width) / 6. + k
* supInv, (j * 2. - height) / 6. + l
* supInv, width / 4);
final RGB rgb = obj.getIntersection(ray);
pixel.add(rgb);
}
}
pixel.scale(supInv * supInv);
imageData[i + width * j] = pixel.toRGB();
}
/*
* Thread.yield(); if (j % 10 == 0) { g.fillRect(0, 50, j, 20);
* //Toolkit.getDefaultToolkit().sync(); }
*/
}
// g.dispose();
// source.newPixels();
}
catch (final InterruptedException ie)
{
// nothing wrong will happen
}
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -