Navigation Menu

Skip to content

Commit

Permalink
Adding next part, not drawing yet
Browse files Browse the repository at this point in the history
  • Loading branch information
abuiles committed Oct 15, 2009
1 parent 6e0f8bc commit 10aef7a
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 42 deletions.
40 changes: 40 additions & 0 deletions src/AST.scala
@@ -0,0 +1,40 @@
import javax.vecmath._;
import scala.Math._;

case class Material(pigment: Color3f)

class SceneElement
class Geometry()

sealed case class Background (color : Color3f) extends SceneElement
sealed case class Camera (location: Vector3d, lookAt: Vector3d) extends SceneElement
sealed case class LightSource (location: Vector3d, color: Color3f) extends SceneElement
sealed case class SceneObject (geometry: Geometry, material: Material) extends SceneElement
sealed case class Plane (point:Vector3d , distance: Double) extends Geometry
case class Sphere(center:Vector3d , radius: Double) extends Geometry {

def intersect (r:Ray, h:Hit, range:Range,material:Color3f): Option [(Hit,Range)]=
{

var v = new Vector3d ( r.origin.x - this.center.x , r.origin.y - this.center.y,r.origin.z - this.center.z);
var discriminant = pow (v.dot (r.direction),2.0) - (pow (v.dot(v),2) - pow (radius,2));
if (discriminant >= 0 )
{
//var t1 = -(v.dot(r.direction)) + sqrt (discriminant);
var t = -(v.dot(r.direction)) - sqrt (discriminant);

if (t >= range.minT && t < range.maxT )
{
var h = new Hit (t,material);
range.maxT = t;

return Some (h,range);
}
return None;

}
else
return None;
}

}
5 changes: 0 additions & 5 deletions src/Camera.scala

This file was deleted.

45 changes: 33 additions & 12 deletions src/Group.scala
@@ -1,18 +1,39 @@
import java.util.Vector;
import javax.vecmath.Color3f;

case class Group (vector : List [Object3D]) extends Object3D
case class Group (var vector:List [SceneElement] )
{
def add ( o3D:Object3D ):Unit = vector ::: List (o3D)
def intersect( r:Ray, h:Hit, range:Range,tMin:TValue ):Boolean =


def intersect( ray:Ray ):Hit =
{
// ToDo:
// Iterate over the array of objects,
// finding the intersections
val retVal = false;
// ...
return retVal;
}
var hit = new Hit (-1,new Color3f ());
var range = new Range ();
println ("aqui");
vector.foreach {
case SceneObject (g,Material (pigment)) =>
g match {
case s:Sphere => {
s.intersect(ray,hit,range,pigment) match{
case Some ((nh,nr)) =>
{
hit = nh;
range = nr;

}
}
}
}
}

// ToDo:
// Iterate over the array of objects,
// finding the intersections

// ...
return hit;
}


}
2 changes: 1 addition & 1 deletion src/Hit.scala
@@ -1,3 +1,3 @@
import javax.vecmath._;

case class Hit ( t:Double , color:Color3f ) // They call super in the constructor.. What for ?
case class Hit ( var t:Double, var color:Color3f)
15 changes: 8 additions & 7 deletions src/Image.scala
@@ -1,18 +1,19 @@
import javax.vecmath._
import java.io._

class Image (width:Int, height:Int)
class Image ()
{

var width = 300;
var height = 300;

var image = Array.ofDim [Point3i] (width,height);
var image = Array.ofDim [Point3d] (width,height);



def setColor(x:Int , y:Int, color:Color3f) {
val myColor = new Point3i((color.x * 255)toInt,
(color.y * 255).toInt,(color.z * 255).toInt);
image(x)(y) = myColor;
def setColor(x:Double , y:Double, color:Color3f) {
val myColor = new Point3d ((color.x * 255).toInt,
(color.y * 255).toInt,(color.z * 255.0).toInt);
image(x.toInt)(y.toInt) = myColor;
}


Expand Down
4 changes: 2 additions & 2 deletions src/Object3D.scala
@@ -1,4 +1,4 @@
abstract class Object3D
abstract class Object3D ()
{
def intersect (r:Ray, h:Hit, range:Range, tMin:TValue): Boolean

}
12 changes: 12 additions & 0 deletions src/OrtographicCamera.scala
@@ -0,0 +1,12 @@
import javax.vecmath._;

case class OrtographicCamera ( size:Double )
{
def generateRay ( point:Point2d ):Ray =
{

var ray = new Ray ( new Point3d(point.getX(),point.getY(),0), new Vector3d(0d,0d,1d));
return ray;
}

}
132 changes: 132 additions & 0 deletions src/Parser.scala
@@ -0,0 +1,132 @@
import java.awt.Color
import javax.vecmath._;
import scala.util.parsing.combinator.lexical._
import scala.util.parsing.combinator.syntactical._

/**
* ExprLexical
* this is copied from this address. Basic support for floatTokens
* http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html
*/
class ExprLexical extends StdLexical {
override def token: Parser[Token] = floatingToken | super.token

def floatingToken: Parser[Token] =
rep1(digit) ~ optFraction ~ optExponent ^^
{ case intPart ~ frac ~ exp => NumericLit(
(intPart mkString "") :: frac :: exp :: Nil mkString "")}

def chr(c:Char) = elem("", ch => ch==c )
def sign = chr('+') | chr('-')
def optSign = opt(sign) ^^ {
case None => ""
case Some(sign) => sign
}
def fraction = '.' ~ rep(digit) ^^ {
case dot ~ ff => dot :: (ff mkString "") :: Nil mkString ""
}
def optFraction = opt(fraction) ^^ {
case None => ""
case Some(fraction) => fraction
}
def exponent = (chr('e') | chr('E')) ~ optSign ~ rep1(digit) ^^ {
case e ~ optSign ~ exp => e :: optSign :: (exp mkString "") :: Nil mkString ""
}
def optExponent = opt(exponent) ^^ {
case None => ""
case Some(exponent) => exponent
}
}

object SceneParser extends StandardTokenParsers {
override val lexical = new ExprLexical
lexical.delimiters ++= List("-","<",">",",","{","}")
lexical.reserved ++= List( "background",
"color",
"camera",
"light_source",
"location",
"look_at",
"pigment",
"plane",
"sphere",
"Blue",
"Green",
"Red",
"Yellow",
"Black",
"White")

// Doesn't accept decimals nor negatives
def valueP = opt("-") ~ numericLit ^^
{case Some(_) ~ s => -s.toDouble
case None ~ s => s.toDouble}


def backgroundP = "background" ~>"{" ~> colorP <~ "}" ^^
{ case color => new Background (new Color3f (color)) }


def colorP = "color" ~> ("Blue" | "Green" | "Red" | "Yellow" | "White" | "Black") ^^
{case "Blue" => Color.blue
case "Green" => Color.green
case "Red" => Color.red
case "Yellow" => Color.yellow
case "White" => Color.white
case "Black" => Color.black
}

def pigmentP = "pigment" ~> "{" ~> colorP <~ "}"

def vectorLitP = ("<" ~> valueP) ~
("," ~> valueP) ~
("," ~> valueP <~ ">") ^^
{case x ~ y ~ z => new Vector3d(x.toDouble,
y.toDouble,
-z.toDouble)}

// This one lifts a common constructor of objects like sphere and plane
def vectorValueP(cons: String, f: Function[(Vector3d, Double, Color3f), SceneObject]) =
(cons ~> "{" ~> vectorLitP) ~
("," ~> valueP ) ~
(pigmentP <~ "}") ^^
{case center ~ radius ~ pigment=> f(center, radius, new Color3f ( pigment ))}

def sphereP =
vectorValueP("sphere", {case (center,radius,pigment) =>
new SceneObject (new Sphere(center, radius), new Material(pigment))})

def planeP =
vectorValueP("plane", {case (center,radius,pigment) =>
new SceneObject (new Plane(center, radius), new Material(pigment))})

def cameraP = ("camera" ~> "{" ~> "location"~> vectorLitP ) ~
( "look_at" ~> vectorLitP <~ "}") ^^
{ case location ~ lookAt => new Camera (location,lookAt) }

def lightP = ("light_source" ~> "{" ~> vectorLitP)~
(colorP <~ "}")^^
{ case location ~ color => new LightSource (location,new Color3f (color)) }

def sceneObjP = sphereP | planeP | cameraP | lightP | backgroundP

// The scene is just a list of SceneObjects
def sceneP: Parser[List[SceneElement]] = sceneObjP+

def parse(s:String) = {
val tokens = new lexical.Scanner(s)
// Check there's only one camera and LightSource.
def checkTree (tree:List[SceneObject]) = (tree count (_.isInstanceOf[Camera])) >=0 &&
(tree count (_.isInstanceOf[LightSource])) >= 0
// lastFailure = None
phrase(sceneP)(tokens) match {
case Success(tree,_) =>
if (true) { // checkTree(tree)
Right(tree)
}else{
Left("Error in the number of cameras or light sources.")
}
case x => Left(x.toString)
}
}
}
5 changes: 4 additions & 1 deletion src/Range.scala
@@ -1 +1,4 @@
case class Range (mintT:Double, maxT:Double)
case class Range () {
var minT:Double =0.0;
var maxT:Double = 50000000;
}
5 changes: 4 additions & 1 deletion src/Ray.scala
@@ -1,6 +1,9 @@
import javax.vecmath._;

case class Ray( origin:Point3d, direction:Vector3d ) //The direction need to be normalized
case class Ray ( var origin:Point3d, var direction:Vector3d )






Expand Down
48 changes: 48 additions & 0 deletions src/SceneCreator.scala
@@ -0,0 +1,48 @@
import javax.vecmath.Point2d;

object Main extends Application {


def process (l:List[SceneElement]):Unit =
{
val size = 300;
var image:Image = new Image ()
var camera = new OrtographicCamera (1d);
var group = new Group ( l );
println ("Got here !!!!!! \n\n ")
for (x <- 0 to size )
{
var px = (x.toDouble/(size/2.0)) - 1.0
for (y <-0 to size)
{
var py = (y.toDouble/(size/2.0)) - 1.0;
var ray = camera.generateRay( new Point2d (px,py));
println ("Is gonna set color");

println (px)
println (py)
group.intersect (ray).color
//image.setColor ( px,py,group.intersect (ray).color );
}
println (x )
}
println ("Writing")
//image.writeImage ();


}


def parseScene() = {
val text = io.Source.fromPath("scene.pov").mkString
SceneParser.parse(text) match {
case Left(err) => {println(err); exit(0);}
case Right(tree) => process(tree);
}
}


parseScene ();


}
13 changes: 0 additions & 13 deletions src/Sphere.scala

This file was deleted.

21 changes: 21 additions & 0 deletions src/scene.pov
@@ -0,0 +1,21 @@
sphere {
<0, 0, 3>,
2.5
pigment {
color Blue
}
}
background {
color Black
}

light_source {
<10, 10, -10>
color White
}

camera {
location <0, 4, -8>
look_at <0, 0, 4>
}

0 comments on commit 10aef7a

Please sign in to comment.