Skip to content

Commit afc332f

Browse files
committed
PR05
1 parent b17c3b5 commit afc332f

File tree

10 files changed

+659
-37
lines changed

10 files changed

+659
-37
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
ISE5783_5657_7716.iml
22
.idea
33
out
4-
images
4+
images
5+
xml

src/parser/SceneDescriptor.java

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package parser;
2+
3+
import javax.xml.parsers.DocumentBuilderFactory;
4+
import javax.xml.parsers.DocumentBuilder;
5+
import javax.xml.parsers.ParserConfigurationException;
6+
7+
import org.w3c.dom.*;
8+
import org.xml.sax.SAXException;
9+
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.*;
13+
14+
/**
15+
* This class parses XML data to data structures relevant to a Scene object
16+
*
17+
* @author Benjamin Mamistvalov, Eyal Nathan
18+
*/
19+
public class SceneDescriptor {
20+
private final Map<String, String> sceneAttributes;
21+
private final Map<String, String> ambientLightAttributes;
22+
private List<Map<String, String>> planes;
23+
private List<Map<String, String>> spheres;
24+
private List<Map<String, String>> triangles;
25+
private final Element root;
26+
private Element geometries;
27+
28+
/**
29+
* Constructor to initialize this class and start parsing the XML file
30+
*
31+
* @param filePath XML file path
32+
* @throws ParserConfigurationException .
33+
* @throws IOException .
34+
* @throws SAXException .
35+
*/
36+
public SceneDescriptor(String filePath)
37+
throws ParserConfigurationException, IOException, SAXException {
38+
this.sceneAttributes = new HashMap<>();
39+
this.ambientLightAttributes = new HashMap<>();
40+
41+
File file = new File(filePath);
42+
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
43+
DocumentBuilder db = dbf.newDocumentBuilder();
44+
Document doc = db.parse(file);
45+
this.root = doc.getDocumentElement();
46+
this.planes = null;
47+
this.spheres = null;
48+
this.triangles = null;
49+
this.geometries = null;
50+
51+
this.parseSceneAttributes();
52+
this.parseAmbientLightAttributes();
53+
54+
if (hasChild(this.root, "geometries")) {
55+
this.geometries = (Element) this.root.getElementsByTagName("geometries").item(0);
56+
this.planes = this.parseGeometry("plane");
57+
this.spheres = this.parseGeometry("sphere");
58+
this.triangles = this.parseGeometry("triangle");
59+
}
60+
}
61+
62+
/**
63+
* Checks if an element has a child with the provided name
64+
*
65+
* @param parent parent element
66+
* @param nodeName child expected name
67+
* @return true if child is present
68+
*/
69+
private static boolean hasChild(Element parent, String nodeName) {
70+
NodeList childNodes = parent.getChildNodes();
71+
int length = childNodes.getLength();
72+
for (int i = 0; i < length; i++)
73+
if (childNodes.item(i).getNodeName().equals(nodeName))
74+
return true;
75+
return false;
76+
}
77+
78+
/**
79+
* Parses the Scene attributes
80+
*/
81+
private void parseSceneAttributes() {
82+
NamedNodeMap attributes = this.root.getAttributes();
83+
int length = attributes.getLength();
84+
85+
Node attribute;
86+
for (int i = 0; i < length; i++) {
87+
attribute = attributes.item(i);
88+
this.sceneAttributes.put(attribute.getNodeName(), attribute.getNodeValue());
89+
}
90+
91+
this.sceneAttributes.putIfAbsent("background-color", "0 0 0");
92+
}
93+
94+
/**
95+
* Parses the Ambient Light attributes
96+
*/
97+
private void parseAmbientLightAttributes() {
98+
if (hasChild(this.root, "ambient-light")) {
99+
NamedNodeMap attributes = this.root.getElementsByTagName("ambient-light").item(0).getAttributes();
100+
int length = attributes.getLength();
101+
102+
Node attribute;
103+
for (int i = 0; i < length; i++) {
104+
attribute = attributes.item(i);
105+
this.ambientLightAttributes.put(attribute.getNodeName(), attribute.getNodeValue());
106+
}
107+
}
108+
109+
this.ambientLightAttributes.putIfAbsent("color", "0 0 0");
110+
this.ambientLightAttributes.putIfAbsent("k", "0");
111+
}
112+
113+
/**
114+
* Parses a specified geometry
115+
*
116+
* @param geometryName specified geometry name
117+
* @return parsed data structure
118+
*/
119+
private List<Map<String, String>> parseGeometry(String geometryName) {
120+
if (!hasChild(this.geometries, geometryName))
121+
return null;
122+
123+
List<Map<String, String>> result = new ArrayList<>();
124+
NodeList requestedGeos = this.geometries.getElementsByTagName(geometryName);
125+
int length = requestedGeos.getLength();
126+
127+
NamedNodeMap attributes;
128+
for (int i = 0; i < length; i++) {
129+
attributes = requestedGeos.item(i).getAttributes();
130+
int attrLength = attributes.getLength();
131+
132+
result.add(new HashMap<>());
133+
134+
Node attribute;
135+
for (int j = 0; j < attrLength; j++) {
136+
attribute = attributes.item(j);
137+
result.get(i).put(attribute.getNodeName(), attribute.getNodeValue());
138+
}
139+
}
140+
141+
return result;
142+
}
143+
144+
/**
145+
* Gets the Scene attributes data structure
146+
*
147+
* @return Scene attributes data structure
148+
*/
149+
public Map<String, String> getSceneAttributes() {
150+
return this.sceneAttributes;
151+
}
152+
153+
/**
154+
* Gets the Ambient Light data structure
155+
*
156+
* @return Ambient Light data structure
157+
*/
158+
public Map<String, String> getAmbientLightAttributes() {
159+
return this.ambientLightAttributes;
160+
}
161+
162+
/**
163+
* Gets the Planes data structure
164+
*
165+
* @return Planes data structure
166+
*/
167+
public List<Map<String, String>> getPlanes() {
168+
return this.planes;
169+
}
170+
171+
/**
172+
* Gets the Spheres data structure
173+
*
174+
* @return Spheres data structure
175+
*/
176+
public List<Map<String, String>> getSpheres() {
177+
return this.spheres;
178+
}
179+
180+
/**
181+
* Gets the Triangles data structure
182+
*
183+
* @return Triangles data structure
184+
*/
185+
public List<Map<String, String>> getTriangles() {
186+
return this.triangles;
187+
}
188+
}

src/primitives/Point.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
public class Point {
99
protected final Double3 xyz;
1010

11+
public static final Point ZERO = new Point(0, 0, 0);
12+
1113
/**
1214
* Constructor to initialize Point based object with its three number values
1315
*

src/renderer/Camera.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class Camera {
2121
private int width;
2222
private double distance;
2323
private ImageWriter imageWriter;
24-
private RayTracerBase rayTracerBase;
24+
private RayTracerBase rayTracer;
2525

2626

2727
/**
@@ -43,6 +43,17 @@ public Camera(Point position, Vector vTo, Vector vUp) throws IllegalArgumentExce
4343
}
4444

4545

46+
/**
47+
* Ray tracing color result
48+
*
49+
* @param ray ray
50+
* @return color
51+
*/
52+
private Color castRay(Ray ray) {
53+
return this.rayTracer.traceRay(ray);
54+
}
55+
56+
4657
/**
4758
* Get the position of the camera
4859
*
@@ -144,11 +155,11 @@ public Camera setImageWriter(ImageWriter imageWriter) {
144155
/**
145156
* Set the Ray Tracer Base
146157
*
147-
* @param rayTracerBase Ray Tracer Base
158+
* @param rayTracer Ray Tracer Base
148159
* @return the updated Camera object
149160
*/
150-
public Camera setRayTracerBase(RayTracerBase rayTracerBase) {
151-
this.rayTracerBase = rayTracerBase;
161+
public Camera setRayTracer(RayTracerBase rayTracer) {
162+
this.rayTracer = rayTracer;
152163
return this;
153164
}
154165

@@ -179,14 +190,12 @@ public Ray constructRay(int nX, int nY, int j, int i) {
179190
return new Ray(this.position, pIJ.subtract(this.position));
180191
}
181192

182-
// TODO: UPDATE THIS JAVADOC
183193
/**
184194
* Renders the image
185195
*
186196
* @throws MissingResourceException if not all fields are initialized
187-
* @throws UnsupportedOperationException PLACEHOLDER
188197
*/
189-
public void renderImage() throws MissingResourceException, UnsupportedOperationException {
198+
public void renderImage() throws MissingResourceException {
190199
if (this.position == null ||
191200
this.vTo == null ||
192201
this.vUp == null ||
@@ -195,12 +204,21 @@ public void renderImage() throws MissingResourceException, UnsupportedOperationE
195204
this.width <= 0 ||
196205
this.distance <= 0 ||
197206
this.imageWriter == null ||
198-
this.rayTracerBase == null)
207+
this.rayTracer == null)
199208
throw new MissingResourceException("Missing resources", "Camera", "");
200-
throw new UnsupportedOperationException("Placeholder");
209+
210+
int xPixels = this.imageWriter.getNx();
211+
int yPixels = this.imageWriter.getNy();
212+
213+
for (int i = 0; i < yPixels; i++) {
214+
for (int j = 0; j < xPixels; j++) {
215+
Ray ray = this.constructRay(xPixels, yPixels, j, i);
216+
Color color = this.castRay(ray);
217+
this.imageWriter.writePixel(j, i, color);
218+
}
219+
}
201220
}
202221

203-
// TODO: UPDATE THIS JAVADOC
204222
/**
205223
* Draws the grid into the image with the provided color
206224
*

src/renderer/RayTracerBase.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public RayTracerBase(Scene scene) {
2121
this.scene = scene;
2222
}
2323

24-
// TODO: IMPROVE THIS JAVADOC
2524
/**
2625
* Returns the color of the first object a given ray intersects with
2726
*

src/renderer/RayTracerBasic.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11
package renderer;
22

33
import primitives.Color;
4+
import primitives.Point;
45
import primitives.Ray;
56
import scene.Scene;
67

8+
import java.util.List;
9+
10+
/**
11+
* This class is a basic RayTracer
12+
*
13+
* @author Benjamin Mamistvalov, Eyal Nathan
14+
*/
715
public class RayTracerBasic extends RayTracerBase {
816
public RayTracerBasic(Scene scene) {
917
super(scene);
1018
}
1119

20+
/**
21+
* Finds the color by a given point
22+
*
23+
* @param point point
24+
* @return color
25+
*/
26+
private Color calcColor(Point point) {
27+
return this.scene.ambientLight.getIntensity(); // TODO: CHANGE THIS TO THE ACTUAL IMPLEMENTATION (after STAGE 5)
28+
}
29+
1230
@Override
1331
public Color traceRay(Ray ray) {
14-
return null;
32+
List<Point> intersections = this.scene.geometries.findIntersections(ray);
33+
34+
if (intersections == null)
35+
return this.scene.background;
36+
37+
return this.calcColor(ray.findClosestPoint(intersections));
1538
}
1639
}

src/scene/Scene.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/**
88
* This class represents a Scene
99
*
10-
* @author Benjamin Mamistvalov
10+
* @author Benjamin Mamistvalov, Eyal Nathan
1111
*/
1212
public class Scene {
1313
public final String name;

0 commit comments

Comments
 (0)