365634146c
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3748 542714f4-19e9-0310-aa3c-eee0fc999fb1
168 lines
5.4 KiB
Java
168 lines
5.4 KiB
Java
//
|
|
// $Id$
|
|
//
|
|
// Narya library - tools for developing networked games
|
|
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
|
|
// http://www.threerings.net/code/narya/
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it
|
|
// under the terms of the GNU Lesser General Public License as published
|
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
package com.threerings.jme.tools;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import com.jme.image.Texture;
|
|
import com.jme.math.FastMath;
|
|
import com.jme.math.Vector3f;
|
|
|
|
/**
|
|
* A tool for converting cube maps (sky boxes) to sphere maps.
|
|
*/
|
|
public class BuildSphereMap
|
|
{
|
|
public static void main (String[] args)
|
|
{
|
|
if (args.length < 7) {
|
|
System.err.println("Usage: BuildSphereMap front.ext back.ext " +
|
|
"left.ext right.ext up.ext dest.ext size");
|
|
System.exit(-1);
|
|
}
|
|
|
|
try {
|
|
execute(new File(args[0]), new File(args[1]), new File(args[2]),
|
|
new File(args[3]), new File(args[4]), new File(args[5]),
|
|
Integer.parseInt(args[6]));
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Builds the sphere map.
|
|
*
|
|
* @param front the file containing the front side of the cube map
|
|
* @param back the file containing the back side of the cube map
|
|
* @param left the file containing the left side of the cube map
|
|
* @param right the file containing the right side of the cube map
|
|
* @param up the file containing the up side of the cube map
|
|
* @param target the file to contain the sphere map
|
|
* @param size the size of the sphere map to generate
|
|
*/
|
|
public static void execute (File front, File back, File left, File right,
|
|
File up, File target, int size)
|
|
throws IOException
|
|
{
|
|
// load up the sides of the cube map
|
|
BufferedImage[] sides = new BufferedImage[5];
|
|
sides[FRONT] = ImageIO.read(front);
|
|
sides[BACK] = ImageIO.read(back);
|
|
sides[LEFT] = ImageIO.read(left);
|
|
sides[RIGHT] = ImageIO.read(right);
|
|
sides[UP] = ImageIO.read(up);
|
|
|
|
// compute the pixels
|
|
int[] rgb = new int[size * size];
|
|
Vector3f vec = new Vector3f();
|
|
for (int y = 0, idx = 0; y < size; y++) {
|
|
for (int x = 0; x < size; x++, idx++) {
|
|
float vx = x / (size*0.5f) - 1f, vy = y / (size*0.5f) - 1f,
|
|
d2 = vx*vx + vy*vy;
|
|
int p = 0;
|
|
if (d2 <= 1f) {
|
|
vec.set(vx, vy, FastMath.sqrt(1f - d2));
|
|
rgb[idx] = getCubeMapPixel(vec, sides);
|
|
}
|
|
}
|
|
}
|
|
|
|
// create and write the image
|
|
BufferedImage image = new BufferedImage(size, size,
|
|
BufferedImage.TYPE_INT_RGB);
|
|
image.setRGB(0, 0, size, size, rgb, 0, size);
|
|
String dest = target.toString(),
|
|
ext = dest.substring(dest.lastIndexOf('.')+1);
|
|
ImageIO.write(image, ext, target);
|
|
}
|
|
|
|
/**
|
|
* Returns the pixel from the cube map to which the given vector points.
|
|
*/
|
|
protected static int getCubeMapPixel (Vector3f vec, BufferedImage[] sides)
|
|
{
|
|
int side = getCubeMapSide(vec);
|
|
|
|
float s, t;
|
|
switch (side) {
|
|
case FRONT:
|
|
s = -vec.x / vec.y;
|
|
t = vec.z / vec.y;
|
|
break;
|
|
case BACK:
|
|
s = -vec.x / vec.y;
|
|
t = -vec.z / vec.y;
|
|
break;
|
|
case LEFT:
|
|
s = vec.y / vec.x;
|
|
t = -vec.z / vec.x;
|
|
break;
|
|
case RIGHT:
|
|
s = vec.y / vec.x;
|
|
t = vec.z / vec.x;
|
|
break;
|
|
default:
|
|
case UP:
|
|
s = vec.x / vec.z;
|
|
t = -vec.y / vec.z;
|
|
break;
|
|
}
|
|
int width = sides[side].getWidth(), height = sides[side].getHeight();
|
|
return sides[side].getRGB((int)((width-1) * (s+1f)/2f),
|
|
(int)((height-1) * (1f-t)/2f));
|
|
}
|
|
|
|
/**
|
|
* Returns the side index identifying the face of the cube map to which
|
|
* the given vector points.
|
|
*/
|
|
protected static int getCubeMapSide (Vector3f vec)
|
|
{
|
|
if (vec.x > vec.z && vec.x > vec.y && vec.x > -vec.y) {
|
|
return RIGHT;
|
|
|
|
} else if (vec.x < -vec.z && vec.x < -vec.y && vec.x < vec.y) {
|
|
return LEFT;
|
|
|
|
} else if (vec.y > vec.z) {
|
|
return FRONT;
|
|
|
|
} else if (vec.y < -vec.z) {
|
|
return BACK;
|
|
|
|
} else {
|
|
return UP;
|
|
}
|
|
}
|
|
|
|
/** The sides of the cube map. */
|
|
protected static final int FRONT = 0, BACK = 1, LEFT = 2, RIGHT = 3,
|
|
UP = 4;
|
|
}
|