More actions
Orthogonal projection coordinate system 만들기
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.m_width = width;
this.m_height = height;
if(buffer == null) {
Util.LOGD("make framebuffer");
world = new World();
m_cam = world.getCamera();
// light mass
world.setAmbientLight(0xff, 0xff, 0xff);
// making background plane
float[] coordinates = { // position of vertices
0.0f, 0.0f, 0.0f,
m_width, 0.0f, 0.0f,
0.0f, m_height, 0.0f,
m_width, m_height, 0.0f
};
float[] uvs = { // how uv mapped?
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
int[] indices = { // index of each coordinate
0, 2, 1,
1, 2, 3
};
// make plane
Object3D plane = new Object3D(coordinates, uvs, indices, RMObject2D.getTextureIDByColor(Color.white));
plane.build();
Util.LOGD("center: " + plane.getTransformedCenter());
world.addObject(plane);
// FOV settings
m_cam.setFOVLimits(0.1f, 2.0f);
m_cam.setFOV(0.1f);
// set up camera
// z = (width/2) / tan(fov/2)
m_cam.setPosition(m_width/2, m_height/2, (float) -(m_width/2/Math.tan(m_cam.getFOV()/2.0f)));
m_cam.lookAt(plane.getTransformedCenter());
fixCubePosition();
// configuration to view far object
Config.farPlane = Math.abs(m_cam.getPosition().z) + 1000f;
}
// make framebuffer
if(buffer != null)
buffer.dispose();
buffer = new FrameBuffer(m_width, m_height, FrameBuffer.SAMPLINGMODE_NORMAL);
}
FillBox class
package cau.rpg.maker.object;
import java.awt.Color;
import javax.vecmath.Vector2f;
import com.threed.jpct.Object3D;
public class RMFillBox extends RMObject2D {
public RMFillBox(float x1, float y1, float x2, float y2, Color color)
{
init(x1, y1, x2, y2, color);
}
public RMFillBox(Vector2f vStart, Vector2f vEnd, Color color)
{
init(vStart.x, vStart.y, vEnd.x, vEnd.y, color);
}
private void init(float x1, float y1, float x2, float y2, Color color)
{
if(x1 >= x2 || y1 >= y2)
return;
float z = -10f;
float[] coords = {
x1, y1, z, // up left
x1, y2, z, // bottom left
x2, y1, z, // up right
x2, y2, z // bottom right corner
};
float[] uvs = {
0f, 0f,
0f, 1f,
1f, 0f,
1f, 1f
};
int[] indices = {
0, 1, 2,
2, 1, 3
};
m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
}
}
2D line class
package cau.rpg.maker.object;
import java.awt.Color;
import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;
import com.threed.jpct.Object3D;
public class RMLine extends RMObject2D {
private static final Vector3f vectorZ = new Vector3f(0, 0, -1);
public RMLine(Vector2f vStart, Vector2f vEnd, float width, Color color)
{
float z = -10f;
Vector3f v3Start = new Vector3f(vStart.x, vStart.y, z);
Vector3f v3End = new Vector3f(vEnd.x, vEnd.y, z);
// line vector
Vector3f lineVector = new Vector3f();
lineVector.sub(v3End, v3Start);
// calc normal vector of line
Vector3f normal = new Vector3f();
normal.cross(lineVector, vectorZ);
normal.normalize();
normal.scale(width/2.0f);
float[] coords = {
(vStart.x + normal.x), (vStart.y + normal.y), z,
(vStart.x - normal.x), (vStart.y - normal.y), z,
(vEnd.x + normal.x), (vEnd.y + normal.y), z,
(vEnd.x - normal.x), (vEnd.y - normal.y), z
};
float[] uvs = {
0f, 0f,
0f, 1f,
1f, 0f,
1f, 1f
};
int[] indices = {
0, 2, 1,
1, 2, 3
};
m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
}
}
Interpolation
public void setDepth(float depth)
{
float delta = depth - this.depth;
// move object
SimpleVector curPosition = m_polygon.getTransformedCenter();
SimpleVector toCam = MainRenderer.getCamera().getPosition().calcSub(curPosition);
float a = MainRenderer.getCamera().getPosition().z - this.depth;
toCam.scalarMul(delta/a);
m_polygon.translate(toCam);
Util.LOGD("translate to " + toCam);
// scale
m_polygon.scale((a-delta)/a);
this.depth = depth;
}
Table 클래스의 구현
# Table class
# a 3-dimensional array2 stores 2Byte integer
# Uses hash table internally.
class Table
def initialize(xsize=1, ysize=1, zsize=1)
resize(xsize, ysize, zsize)
end
def resize xsize, ysize, zsize
@array = Hash.new
@xsize = xsize
@ysize = ysize
@zsize = zsize
end
def self.resize xsize, ysize, zsize
#puts "resize to (#{xsize}, #{ysize}, #{zsize})"
@array = Hash.new
@xsize = xsize
@ysize = ysize
@zsize = zsize
end
def [] *args
x=0
y=0
z=0
if args.length > 0
x = args[0]
end
if args.length > 1
y = args[1]
end
if args.length > 2
z = args[2]
end
return @arrayx, y, z
end
def []= *args
value = args[args.size-1]
args.delete_at(args.size-1)
x=0
y=0
z=0
if args.length > 0
x = args[0]
end
if args.length > 1
y = args[1]
end
if args.length > 2
z = args[2]
end
@arrayx, y, z = value
end
def self._load args
#puts "load table"
header = args.unpack("l5")
table = args.unpack("@20s*")
#puts header.inspect
#puts table.inspect
obj = Table.new(header[1], header[2], header[3])
i=-1
for z in 0 ... obj.zsize
for y in 0 ... obj.ysize
for x in 0 ... obj.xsize
obj[x, y, z] = table[i = i+1]
#puts "array put #{table[i]}"
end
end
end
return obj
end
attr_accessor :xsize
attr_accessor :ysize
attr_accessor :zsize
end
Color 클래스의 구현
알만툴에서 사용하는 Color 클래스이다.
내부적으로 자바의 java.awt.Color 클래스를 가지고 있으며 이를 이용하여 모든 값을 주고받는다.
루비의 Color와 자바의 Color이 이름이 같기 때문에 자바의 Color을 임시 모듈에 담아 모호성을 해결하였다.
require 'java'
# use temporary namespace(module) to solve ambiguous class name
module AA
import 'java.awt.Color'
end
class Color
attr_reader :object
def initialize red, green, blue, alpha=255
@object = AA::Color.new(red, green, blue, alpha)
end
def set red, green, blue, alpha=255
@object = AA::Color.new(red, green, blue, alpha)
end
def red
return @object.getRed
end
def green
return @object.getGreen
end
def blue
return @object.getBlue
end
def alpha
return @object.getAlpha
end
def self._load args
# convert to floting point value
value = args.unpack("d4")
return Color.new(value[0].to_i, value[1].to_i, value[2].to_i, value[3].to_i)
end
def to_i
return (red | (green << 8) | (blue << 16) | (alpha << 24))
end
def red= r
r = adjust_value(r, 0, 255)
set(r, green, blue, alpha)
end
def green= g
g = adjust_value(g, 0, 255)
set(red, g, blue, alpha)
end
def blue= b
b = adjust_value(b, 0, 255)
set(red, green, b, alpha)
end
def alpha= a
a = adjust_value(a, 0, 255)
set(red, green, blue, a)
end
end