mirror of
https://github.com/alterdekim/Simple-3DEngine.git
synced 2025-04-08 11:10:31 +03:00
Initial commit
This commit is contained in:
commit
046ad98e83
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Project exclude paths
|
||||
/out/
|
13
src/com/alterdekim/rendering/AmbientLight.java
Normal file
13
src/com/alterdekim/rendering/AmbientLight.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class AmbientLight extends Light {
|
||||
|
||||
public AmbientLight(Vector3 position) {
|
||||
super(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateBrightness( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
7
src/com/alterdekim/rendering/Camera.java
Normal file
7
src/com/alterdekim/rendering/Camera.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Camera extends Object3D {
|
||||
public Camera(Vector3 position) {
|
||||
super(position);
|
||||
}
|
||||
}
|
29
src/com/alterdekim/rendering/Canvas.java
Normal file
29
src/com/alterdekim/rendering/Canvas.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Canvas extends Raymarcher {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Sphere sphere = new Sphere( new Vector3(0,0,0), 1 );
|
||||
private LambertLight light = new LambertLight(new Vector3(4,2,4));
|
||||
private double d = 0;
|
||||
|
||||
public Canvas() {
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
this.setCameraPosition(new Vector3(0, 0, -3));
|
||||
sphere.getMaterial().setColor(new MaterialColor(0.3, 0.7, 1.0));
|
||||
this.add(sphere);
|
||||
this.add(new Plane(new Vector3(0,0,0)));
|
||||
this.addLight(light);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRender() {
|
||||
light.setPosition(new Vector3(4.0*Math.sin(d), 2.0, 4.0 * Math.cos(d)));
|
||||
d+=0.2;
|
||||
}
|
||||
}
|
13
src/com/alterdekim/rendering/FOGLight.java
Normal file
13
src/com/alterdekim/rendering/FOGLight.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class FOGLight extends Light {
|
||||
|
||||
public FOGLight(Vector3 position) {
|
||||
super(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateBrightness( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
return 1.0 - Utils.clamp( Utils.rangeConvert( d, 0, 3.6, 0, 1 ), 0.0, 1.0 );
|
||||
}
|
||||
}
|
19
src/com/alterdekim/rendering/LambertLight.java
Normal file
19
src/com/alterdekim/rendering/LambertLight.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class LambertLight extends Light {
|
||||
|
||||
public LambertLight(Vector3 position) {
|
||||
super(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateBrightness( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
Vector3 lightDirection = this.calculateLightDirection(rd, ro, normal, d);
|
||||
return Utils.clamp(lightDirection.dot(normal), 0.0, 1.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 calculateLightDirection( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
return new Vector3( this.getX(), this.getY(), this.getZ() ).subtract(rd.multiply(d).sum(ro)).normalize();
|
||||
}
|
||||
}
|
62
src/com/alterdekim/rendering/Light.java
Normal file
62
src/com/alterdekim/rendering/Light.java
Normal file
@ -0,0 +1,62 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Light {
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
|
||||
public Light( Vector3 position ) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.z = position.z;
|
||||
}
|
||||
|
||||
public void setPosition( double x, double y, double z ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void setPosition( Vector3 position ) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.z = position.z;
|
||||
}
|
||||
|
||||
public Vector3 getPosition() {
|
||||
return new Vector3( this.x, this.y, this.z );
|
||||
}
|
||||
|
||||
public void setX( double x ) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY( double y ) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setZ( double z ) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
public double calculateBrightness( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Vector3 calculateLightDirection( Vector3 rd, Vector3 ro, Vector3 normal, double d ) {
|
||||
return new Vector3(0,0,0);
|
||||
}
|
||||
}
|
17
src/com/alterdekim/rendering/Material.java
Normal file
17
src/com/alterdekim/rendering/Material.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Material {
|
||||
private MaterialColor color;
|
||||
|
||||
public Material( MaterialColor color ) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public MaterialColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public void setColor( MaterialColor color ) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
26
src/com/alterdekim/rendering/MaterialColor.java
Normal file
26
src/com/alterdekim/rendering/MaterialColor.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class MaterialColor {
|
||||
|
||||
private double hue;
|
||||
private double saturation;
|
||||
private double brightness;
|
||||
|
||||
public MaterialColor( double hue, double saturation, double brightness ) {
|
||||
this.hue = hue;
|
||||
this.saturation = saturation;
|
||||
this.brightness = brightness;
|
||||
}
|
||||
|
||||
public double getHue() {
|
||||
return this.hue;
|
||||
}
|
||||
|
||||
public double getSaturation() {
|
||||
return this.saturation;
|
||||
}
|
||||
|
||||
public double getBrightness() {
|
||||
return this.brightness;
|
||||
}
|
||||
}
|
88
src/com/alterdekim/rendering/Object3D.java
Normal file
88
src/com/alterdekim/rendering/Object3D.java
Normal file
@ -0,0 +1,88 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Object3D {
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private double rotationX = 0;
|
||||
private double rotationY = 0;
|
||||
private double rotationZ = 0;
|
||||
private Material mat = new Material(new MaterialColor(0,0,0));
|
||||
|
||||
public Object3D( Vector3 position ) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.z = position.z;
|
||||
}
|
||||
|
||||
public void setMaterial( Material mat ) {
|
||||
this.mat = mat;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return this.mat;
|
||||
}
|
||||
|
||||
public void setPosition( Vector3 position ) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.z = position.z;
|
||||
}
|
||||
|
||||
public void setRotationX( double x ) {
|
||||
this.rotationX = x;
|
||||
}
|
||||
|
||||
public void setRotationY( double y ) {
|
||||
this.rotationY = y;
|
||||
}
|
||||
|
||||
public void setRotationZ( double z ) {
|
||||
this.rotationZ = z;
|
||||
}
|
||||
|
||||
public double getEulerX() {
|
||||
return this.rotationX;
|
||||
}
|
||||
|
||||
public double getEulerY() {
|
||||
return this.rotationY;
|
||||
}
|
||||
|
||||
public double getEulerZ() {
|
||||
return this.rotationZ;
|
||||
}
|
||||
|
||||
public Vector3 getPosition() {
|
||||
return new Vector3( this.x, this.y, this.z );
|
||||
}
|
||||
|
||||
public void setX( double x ) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY( double y ) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setZ( double z ) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
public double calculateSDF(Vector3 position) {
|
||||
return 0;
|
||||
}
|
||||
}
|
31
src/com/alterdekim/rendering/Octahedron.java
Normal file
31
src/com/alterdekim/rendering/Octahedron.java
Normal file
@ -0,0 +1,31 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Octahedron extends Object3D {
|
||||
|
||||
private double size;
|
||||
|
||||
public Octahedron(Vector3 position, double size) {
|
||||
super(position);
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public double getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateSDF( Vector3 position ) {
|
||||
if( this.getEulerX() != 0 ) {
|
||||
position = position.cross(Utils.rotateX(Math.toRadians(this.getEulerX())));
|
||||
}
|
||||
if( this.getEulerY() != 0 ) {
|
||||
position = position.cross(Utils.rotateY(Math.toRadians(this.getEulerY())));
|
||||
}
|
||||
if( this.getEulerZ() != 0 ) {
|
||||
position = position.cross(Utils.rotateZ(Math.toRadians(this.getEulerZ())));
|
||||
}
|
||||
position = new Vector3(Math.abs(position.x), Math.abs(position.y), Math.abs(position.z));
|
||||
return (position.x+position.y+position.z-size)*0.57735027;
|
||||
}
|
||||
|
||||
}
|
12
src/com/alterdekim/rendering/Plane.java
Normal file
12
src/com/alterdekim/rendering/Plane.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Plane extends Object3D {
|
||||
public Plane(Vector3 position) {
|
||||
super(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateSDF( Vector3 position ) {
|
||||
return (position.y *(-1)) + 1.0 + this.getY();
|
||||
}
|
||||
}
|
170
src/com/alterdekim/rendering/Raymarcher.java
Normal file
170
src/com/alterdekim/rendering/Raymarcher.java
Normal file
@ -0,0 +1,170 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class Raymarcher extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final int MAX_STEPS = 80;
|
||||
|
||||
private final double MAX_DIST = 100.0;
|
||||
|
||||
private final double SURF_DIST = 0.001;
|
||||
|
||||
private final Camera camera = new Camera(new Vector3(0,0,0));
|
||||
|
||||
private ArrayList<Object3D> objects = new ArrayList<Object3D>();
|
||||
|
||||
private ArrayList<Light> lights = new ArrayList<Light>();
|
||||
|
||||
public void init() {
|
||||
Runnable task = new Runnable() {
|
||||
public void run() {
|
||||
while(true) {
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
onStart();
|
||||
Thread thread = new Thread(task);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void onStart() {}
|
||||
|
||||
public void onRender() {}
|
||||
|
||||
private sceneResult raymarch(Vector3 ro, Vector3 rd) {
|
||||
double depth = 0;
|
||||
Material mat = new Material(new MaterialColor(0,0,0));
|
||||
for( int i = 0; i < MAX_STEPS; i++ ) {
|
||||
Vector3 p = rd.multiply(depth).sum(ro);
|
||||
sceneResult res = sceneSDF( p );
|
||||
double dS = res.dist;
|
||||
mat = res.mat;
|
||||
depth += dS;
|
||||
if( dS < SURF_DIST || depth > MAX_DIST ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new sceneResult( depth, mat );
|
||||
}
|
||||
|
||||
private sceneResult sceneSDF( Vector3 pos ) {
|
||||
double min = MAX_DIST;
|
||||
Material mat = new Material(new MaterialColor(0,0,0));
|
||||
for( int i = 0; i < this.objects.size(); i++ ) {
|
||||
double d = this.objects.get(i).calculateSDF(pos);
|
||||
if( d < min ) {
|
||||
min = d;
|
||||
mat = this.objects.get(i).getMaterial();
|
||||
}
|
||||
}
|
||||
return new sceneResult(min, mat);
|
||||
}
|
||||
|
||||
public void setCameraPosition( Vector3 position ) {
|
||||
this.camera.setPosition(position);
|
||||
}
|
||||
|
||||
public void setCameraRotation( Vector3 rotation ) {
|
||||
this.camera.setRotationX(rotation.x);
|
||||
this.camera.setRotationY(rotation.y);
|
||||
this.camera.setRotationZ(rotation.z);
|
||||
}
|
||||
|
||||
public Camera getCamera() {
|
||||
return this.camera;
|
||||
}
|
||||
|
||||
public void add( Object3D object ) {
|
||||
this.objects.add(object);
|
||||
}
|
||||
|
||||
public void remove( Object3D object ) {
|
||||
this.objects.remove(object);
|
||||
}
|
||||
|
||||
public ArrayList<Object3D> children() {
|
||||
return this.objects;
|
||||
}
|
||||
|
||||
public void addLight( Light light ) {
|
||||
this.lights.add(light);
|
||||
}
|
||||
|
||||
public void removeLight( Light light ) {
|
||||
this.lights.remove(light);
|
||||
}
|
||||
|
||||
public ArrayList<Light> childrenLight() {
|
||||
return this.lights;
|
||||
}
|
||||
|
||||
private Vector3 calcNormal( Vector3 pos ) {
|
||||
Vector3 xyy = new Vector3(SURF_DIST,0,0);
|
||||
Vector3 yxy = new Vector3(0,SURF_DIST,0);
|
||||
Vector3 yyx = new Vector3(0,0,SURF_DIST);
|
||||
|
||||
Vector3 nor = new Vector3(
|
||||
sceneSDF(pos.sum(xyy)).dist - sceneSDF(pos.subtract(xyy)).dist,
|
||||
sceneSDF(pos.sum(yxy)).dist - sceneSDF(pos.subtract(yxy)).dist,
|
||||
sceneSDF(pos.sum(yyx)).dist - sceneSDF(pos.subtract(yyx)).dist);
|
||||
return nor.normalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onRender();
|
||||
Vector3 ro = new Vector3( camera.getX(), camera.getY(), camera.getZ() );
|
||||
double minres = Math.min(getWidth(), getHeight());
|
||||
for( int x = 0; x < getWidth(); x++ ) {
|
||||
for( int y = 0; y < getHeight(); y++ ) {
|
||||
Vector3 rd = new Vector3((((double)x) - 0.5* ((double) getWidth())) / minres, (((double)y) - 0.5* ((double) getHeight())) / minres, 1);
|
||||
if( camera.getEulerX() != 0 ) {
|
||||
rd = rd.cross(Utils.rotateX(Math.toRadians(camera.getEulerX())));
|
||||
}
|
||||
if( camera.getEulerY() != 0 ) {
|
||||
rd = rd.cross(Utils.rotateY(Math.toRadians(camera.getEulerY())));
|
||||
}
|
||||
if( camera.getEulerZ() != 0 ) {
|
||||
rd = rd.cross(Utils.rotateZ(Math.toRadians(camera.getEulerZ())));
|
||||
}
|
||||
rd = rd.normalize();
|
||||
sceneResult res = raymarch( ro, rd );
|
||||
double d = res.dist;
|
||||
if( d < MAX_DIST ) {
|
||||
double dif = 0;
|
||||
Vector3 p = rd.multiply(d).sum(ro);
|
||||
Vector3 normal = calcNormal(p);
|
||||
for( int i = 0; i < this.lights.size(); i++ ) {
|
||||
dif += this.lights.get(i).calculateBrightness(rd, ro, normal, d);
|
||||
dif = Utils.clamp( dif, 0.0, 1.0 );
|
||||
}
|
||||
g.setColor(Color.getHSBColor( (float)res.mat.getColor().getHue(), (float)res.mat.getColor().getSaturation(), (float)dif ));
|
||||
} else {
|
||||
g.setColor(Color.BLACK);
|
||||
}
|
||||
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class sceneResult {
|
||||
public double dist;
|
||||
public Material mat;
|
||||
|
||||
public sceneResult( double dist, Material mat ) {
|
||||
this.dist = dist;
|
||||
this.mat = mat;
|
||||
}
|
||||
}
|
||||
}
|
40
src/com/alterdekim/rendering/RenderingWindow.java
Normal file
40
src/com/alterdekim/rendering/RenderingWindow.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
public class RenderingWindow {
|
||||
|
||||
private JFrame frmRendering;
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
RenderingWindow window = new RenderingWindow();
|
||||
window.frmRendering.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public RenderingWindow() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
frmRendering = new JFrame();
|
||||
frmRendering.setTitle("Rendering");
|
||||
frmRendering.setResizable(false);
|
||||
frmRendering.setBounds(100, 100, 400, 400);
|
||||
frmRendering.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
Canvas panel = new Canvas();
|
||||
frmRendering.getContentPane().add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
}
|
29
src/com/alterdekim/rendering/Sphere.java
Normal file
29
src/com/alterdekim/rendering/Sphere.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Sphere extends Object3D {
|
||||
|
||||
private double radius;
|
||||
|
||||
public Sphere( Vector3 position, double radius ) {
|
||||
super( position );
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return this.radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateSDF( Vector3 position ) {
|
||||
if( this.getEulerX() != 0 ) {
|
||||
position = position.cross(Utils.rotateX(Math.toRadians(this.getEulerX())));
|
||||
}
|
||||
if( this.getEulerY() != 0 ) {
|
||||
position = position.cross(Utils.rotateY(Math.toRadians(this.getEulerY())));
|
||||
}
|
||||
if( this.getEulerZ() != 0 ) {
|
||||
position = position.cross(Utils.rotateZ(Math.toRadians(this.getEulerZ())));
|
||||
}
|
||||
return position.subtract(this.getPosition()).length() - this.getRadius();
|
||||
}
|
||||
}
|
48
src/com/alterdekim/rendering/Triangle.java
Normal file
48
src/com/alterdekim/rendering/Triangle.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
public class Triangle extends Object3D {
|
||||
|
||||
private Vector3 a;
|
||||
private Vector3 b;
|
||||
private Vector3 c;
|
||||
|
||||
public Triangle(Vector3 position, Vector3 a, Vector3 b, Vector3 c) {
|
||||
super(position);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateSDF(Vector3 p) {
|
||||
if( this.getEulerX() != 0 ) {
|
||||
p = p.cross(Utils.rotateX(Math.toRadians(this.getEulerX())));
|
||||
}
|
||||
if( this.getEulerY() != 0 ) {
|
||||
p = p.cross(Utils.rotateY(Math.toRadians(this.getEulerY())));
|
||||
}
|
||||
if( this.getEulerZ() != 0 ) {
|
||||
p = p.cross(Utils.rotateZ(Math.toRadians(this.getEulerZ())));
|
||||
}
|
||||
Vector3 ba = b.subtract(a); Vector3 pa = p.subtract(a);
|
||||
Vector3 cb = c.subtract(b); Vector3 pb = p.subtract(b);
|
||||
Vector3 ac = a.subtract(c); Vector3 pc = p.subtract(c);
|
||||
Vector3 nor = ba.cross(ac);
|
||||
|
||||
return Math.sqrt(
|
||||
(Math.signum(ba.cross(nor).dot(pa)) +
|
||||
Math.signum(cb.cross(nor).dot(pb)) +
|
||||
Math.signum(ac.cross(nor).dot(pc))<2.0)
|
||||
?
|
||||
Math.min( Math.min(
|
||||
dot2(ba.multiply(Utils.clamp(ba.dot(pa)/dot2(ba),0.0,1.0)).subtract(pa)),
|
||||
dot2(cb.multiply(Utils.clamp(cb.dot(pb)/dot2(cb),0.0,1.0)).subtract(pb)) ),
|
||||
dot2(ac.multiply(Utils.clamp(ac.dot(pc)/dot2(ac),0.0,1.0)).subtract(pc)) )
|
||||
:
|
||||
nor.dot(pa)*nor.dot(pa)/dot2(nor) );
|
||||
}
|
||||
|
||||
private double dot2( Vector3 v ) {
|
||||
return v.dot(v);
|
||||
}
|
||||
}
|
47
src/com/alterdekim/rendering/Utils.java
Normal file
47
src/com/alterdekim/rendering/Utils.java
Normal file
@ -0,0 +1,47 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static double rangeConvert( double value, double leftMin, double leftMax, double rightMin, double rightMax ) {
|
||||
double leftSpan = leftMax - leftMin;
|
||||
double rightSpan = rightMax - rightMin;
|
||||
double valueScaled = (value - leftMin) / (leftSpan);
|
||||
return rightMin + (valueScaled * rightSpan);
|
||||
}
|
||||
|
||||
public static double clamp( double value, double MIN_VALUE, double MAX_VALUE ) {
|
||||
return (value > MAX_VALUE ? MAX_VALUE : value < MIN_VALUE ? MIN_VALUE : value);
|
||||
}
|
||||
|
||||
public static ArrayList<Vector3> rotateX(double theta) {
|
||||
double c = Math.cos(theta);
|
||||
double s = Math.sin(theta);
|
||||
ArrayList<Vector3> v = new ArrayList<Vector3>();
|
||||
v.add(new Vector3(1, 0, 0));
|
||||
v.add(new Vector3(0, c, -s));
|
||||
v.add(new Vector3(0, s, c));
|
||||
return v;
|
||||
}
|
||||
|
||||
public static ArrayList<Vector3> rotateY(double theta) {
|
||||
double c = Math.cos(theta);
|
||||
double s = Math.sin(theta);
|
||||
ArrayList<Vector3> v = new ArrayList<Vector3>();
|
||||
v.add(new Vector3(c, 0, s));
|
||||
v.add(new Vector3(0, 1, 0));
|
||||
v.add(new Vector3(-s, 0, c));
|
||||
return v;
|
||||
}
|
||||
|
||||
public static ArrayList<Vector3> rotateZ(double theta) {
|
||||
double c = Math.cos(theta);
|
||||
double s = Math.sin(theta);
|
||||
ArrayList<Vector3> v = new ArrayList<Vector3>();
|
||||
v.add(new Vector3(c, -s, 0));
|
||||
v.add(new Vector3(s, c, 0));
|
||||
v.add(new Vector3(0, 0, 1));
|
||||
return v;
|
||||
}
|
||||
}
|
71
src/com/alterdekim/rendering/Vector3.java
Normal file
71
src/com/alterdekim/rendering/Vector3.java
Normal file
@ -0,0 +1,71 @@
|
||||
package com.alterdekim.rendering;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Vector3 {
|
||||
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
public Vector3( double x, double y, double z ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public Vector3 subtract( Vector3 s ) {
|
||||
return new Vector3( this.x - s.x, this.y - s.y, this.z - s.z );
|
||||
}
|
||||
|
||||
public Vector3 multiply( double num ) {
|
||||
return new Vector3( this.x * num, this.y * num, this.z * num );
|
||||
}
|
||||
|
||||
public Vector3 divide( double num ) {
|
||||
return new Vector3( this.x / num, this.y / num, this.z / num );
|
||||
}
|
||||
|
||||
public Vector3 sum( Vector3 s ) {
|
||||
return new Vector3( this.x + s.x, this.y + s.y, this.z + s.z );
|
||||
}
|
||||
|
||||
public double dot( Vector3 s ) {
|
||||
return (this.x * s.x) + (this.y * s.y) + (this.z * s.z);
|
||||
}
|
||||
|
||||
public Vector3 normalize() {
|
||||
Vector3 v3 = new Vector3(0,0,0);
|
||||
|
||||
double length = Math.sqrt( this.x*this.x + this.y*this.y + this.z*this.z );
|
||||
if (length != 0) {
|
||||
v3.x = this.x/length;
|
||||
v3.y = this.y/length;
|
||||
v3.z = this.z/length;
|
||||
}
|
||||
|
||||
return v3;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt( this.x*this.x + this.y*this.y + this.z*this.z );
|
||||
}
|
||||
|
||||
public Vector3 cross( Vector3 c ) {
|
||||
return new Vector3( (this.y * c.z) - (this.z * c.y),
|
||||
(this.z * c.x) - (this.x * c.z),
|
||||
(this.x * c.y) - (this.y * c.x));
|
||||
}
|
||||
|
||||
public Vector3 cross( ArrayList<Vector3> matrix ) {
|
||||
Vector3 result = new Vector3( this.x, this.y, this.z );
|
||||
result.x = (matrix.get(0).x * this.x) + (matrix.get(0).y * this.y) + (matrix.get(0).z * this.z);
|
||||
result.y = (matrix.get(1).x * this.x) + (matrix.get(1).y * this.y) + (matrix.get(1).z * this.z);
|
||||
result.z = (matrix.get(2).x * this.x) + (matrix.get(2).y * this.y) + (matrix.get(2).z * this.z);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Vector3 reflect( Vector3 normal, Vector3 v ) {
|
||||
return v.subtract(normal.multiply(2).cross(v).cross(normal));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user