Permalink
Browse files

* Added the spotlight implementation.

* Geometry now how an isCollidable method which pre-processes a ray before executing the hit test.
* Added an isVisible method to SceneObject -- this is useful for hiding lights in the scene.
  • Loading branch information...
mbolt35 committed May 22, 2011
1 parent 4983be3 commit 0a8722b67fbc0e259d952a9c139e8d93cd1d3e51
@@ -63,7 +63,7 @@ public static void main(String[] args) {
.toString());
Camera camera = new Camera(new Vector3(4, 3, 3));
- Scene scene = getSceneTwo(configuration);
+ Scene scene = getSceneThree(configuration);
long t = new Date().getTime();
@@ -72,7 +72,7 @@ public static void main(String[] args) {
final ImageTarget image = new ImageTarget("test", ImageTarget.ImageType.PNG, view.getWidth(), view.getHeight());
final WindowTarget window = new WindowTarget(1900, 0, view.getWidth(), view.getHeight());
- new RayTracer(configuration).render(scene, view, camera, window);
+ new RayTracer(configuration).render(scene, view, camera, image);
long totalTime = ((new Date().getTime() - t) / 1000);
logger.debug("Complete! Took: " + totalTime + "seconds");
@@ -122,16 +122,16 @@ private static Scene getSceneThree(JavaRayConfiguration configuration) {
//scene.add( new Light(new Vector3(4, 16, -3), 12, 1) );
// SpotLights
- scene.add( new SpotLight(new Vector3(4, 4, 3), new Vector3(4, 0, -7), new ColorMagnitude(0, 10, 0), 1, 20.0) );
- scene.add( new SpotLight(new Vector3(0, 4, 2), new Vector3(4, 0, -7), new ColorMagnitude(10, 0, 0), 1, 20.0) );
- scene.add( new SpotLight(new Vector3(8, 4, 2), new Vector3(4, 0, -7), new ColorMagnitude(0, 0, 10), 1, 20.0) );
+ scene.add( new SpotLight(new Vector3(4, 4, 3), new Vector3(4, 0, -4), new ColorMagnitude(0, 32, 0), 1, 25.0) );
+ scene.add( new SpotLight(new Vector3(0, 4, 2), new Vector3(4, 0, -4), new ColorMagnitude(32, 0, 0), 1, 25.0) );
+ scene.add( new SpotLight(new Vector3(8, 4, 2), new Vector3(4, 0, -4), new ColorMagnitude(0, 0, 32), 1, 25.0) );
// Planes
- scene.add( new Plane(new Vector3(0, 0, -28), new Vector3(0, 0, 1), newMat(2, 2, 2, 3.2, 3.2, 3.2, 0, 0, 0)) );
+ scene.add( new Plane(new Vector3(0, 0, -20), new Vector3(0, 0, 1), newMat(2, 2, 2, 3.2, 3.2, 3.2, 0, 0, 0)) );
scene.add( new Plane(new Vector3(0, 0, 0), new Vector3(0, 1, 0), newMat(2, 2, 2, 3.2, 3.2, 3.2, 0, 0, 0)) );
// Spheres
- //scene.add( new Sphere(new Vector3(4, 3, -3), newMat(0, 0, 0, 5, 5, 5, 1, 1, 1), 2.0) );
+ scene.add( new Sphere(new Vector3(4, 4, -4), newMat(0, 0, 0, 5, 5, 5, 1, 1, 1), 3.0) );
return scene;
}
@@ -30,18 +30,30 @@
/**
* This method detects a hit from the ray.
*
- * @param ray
+ * @param ray The {@link Ray} to test for a hit.
*
- * @return
+ * @return The {@link HitResult} of the test.
*/
HitResult hits(Ray ray);
/**
- * This method finds
- * @param
+ * This method finds the {@code Vector3} normal to the object.
+ *
+ * @param point The {@code Vector3} to find the normal to.
+ *
+ * @return The normal for the point provided.
*/
Vector3 normalTo(Vector3 point);
+ /**
+ * This method determines whether or not it is appropriate to check for a collision or not.
+ *
+ * @param ray The {@link Ray} used to determine whether or not the object is collidable.
+ *
+ * @return {@code true} if the object is collidable.
+ */
+ boolean isCollidable(Ray ray);
+
/**
* This class is used to represent a hit result.
*/
@@ -79,6 +79,11 @@ public Vector3 normalTo(Vector3 point) {
return normal;
}
+ @Override
+ public boolean isCollidable(Ray ray) {
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -26,7 +26,7 @@
import com.mattbolt.javaray.render.Material;
/**
- *
+ * This class represents a light source
*/
public class Light extends Sphere implements SceneObject {
@@ -27,7 +27,6 @@
import com.mattbolt.javaray.primitives.SceneObject;
import com.mattbolt.javaray.render.ColorMagnitude;
import com.mattbolt.javaray.render.Material;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,37 +55,37 @@ public Geometry getGeometry() {
return geometry;
}
+ @Override
+ public boolean isVisible() {
+ return false;
+ }
+
/**
* spotlight geometry
*/
private static class SpotGeometry extends SphereGeometry implements Geometry {
private final Vector3 position;
private final Vector3 target;
+ private final Vector3 lightDirection;
private final double theta;
private SpotGeometry(Vector3 position, Vector3 target, double radius, double theta) {
super(position, radius);
this.position = new Vector3(position);
this.target = new Vector3(target);
- this.theta = theta;
+ this.lightDirection = Vector3.subtract(position, target);
+ this.theta = Math.cos(Math.PI * (theta / 180.0));
+
+ lightDirection.normalize();
}
@Override
- public HitResult hits(Ray ray) {
- Vector3 difference = Vector3.subtract(position, ray.getPosition());
- Vector3 direction = Vector3.subtract(position, target);
- difference.normalize();
- direction.normalize();
-
- double angle = Vector3.dotProduct(difference, direction);
- //logger.debug("angle: {}", angle);
-
- if (angle < theta) {
- return new HitResult(-1, null);
- }
-
- return super.hits(ray);
+ public boolean isCollidable(Ray ray) {
+ double angle = Vector3.dotProduct(ray.getDirection(), lightDirection);
+ // logger.debug("angle: {}", angle);
+
+ return angle > theta;
}
@Override
@@ -57,6 +57,10 @@ public boolean isEmittingLight() {
return emissivity.getRed() > 0 || emissivity.getGreen() > 0 || emissivity.getBlue() > 0;
}
+ public boolean isVisible() {
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -108,6 +108,11 @@ public Vector3 normalTo(Vector3 point) {
return planeNormal;
}
+ @Override
+ public boolean isCollidable(Ray ray) {
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -52,4 +52,11 @@
*/
boolean isEmittingLight();
+ /**
+ * This method returns {@code true} if the object is visible in the scene and/or relfections.
+ *
+ * @return {@code true} if the object is visible.
+ */
+ boolean isVisible();
+
}
@@ -122,7 +122,7 @@ private Vector3 rayTrace( List<SceneObject> objects,
Ray ray = new Ray(viewPoint, direction);
for (SceneObject object : objects) {
- if (!object.equals(lastHit)) {
+ if (!object.equals(lastHit) && object.isVisible()) {
Geometry objectGeometry = object.getGeometry();
Geometry.HitResult result = objectGeometry.hits(ray);
Vector3 hitPoint = result.getHitPoint();
@@ -238,6 +238,10 @@ private boolean isLightVisible( List<SceneObject> objects,
Ray ray = new Ray(hitPoint, difference);
+ if (!lightSource.getGeometry().isCollidable(ray)) {
+ return false;
+ }
+
for (SceneObject object : objects) {
if (!object.equals(hitObject) && !object.equals(lightSource)) {
Geometry.HitResult result = object.getGeometry().hits(ray);

0 comments on commit 0a8722b

Please sign in to comment.