2

I am implementing a ray tracer and am having trouble with basic Java references :/ I have been staring at this for a while and I can't see the problem...

IntersectResult ir = new IntersectResult();
root.intersect(ray, ir);

if(r.material!=null)
    System.out.println(result.material.diffuse);
// Doesn't print at all!!

// in my Node Class...
@Override
public void intersect(Ray ray, IntersectResult result) {

    IntersectResult i = new IntersectResult();
    for (Intersectable child:children){
        child.intersect(ray, i);
        if (result.t>i.t)
            result = new IntersectResult(i);
    }
    if(result.material!=null)
    System.out.println(result.material.diffuse); // prints correctly!
}

Basically my question is why is result.material null after the intersect method call when the print statements within the method call show that it is not?

spatara
  • 893
  • 4
  • 15
  • 28
  • where is r declared? Also, [this](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) question might help. – Dennis Meng Nov 22 '13 at 20:11
  • What is `r.material` referring to? Do you happen to mean `ir`? Also, shouldn't the `system.out.println` reference `ir` as well? – Compass Nov 22 '13 at 20:11

1 Answers1

2

This is a classic case of how the "pass-by-value" approach works and it is not specific to the code in question.

With respect to the latter, the ir reference passed to the intersect() method is redirected by the statement

result = new IntersectResult(i);

So, whenever the above statement is executed, the material object created is not saved in the original material variable, but to a local one, which is lost after the intersect method returns.

If you want to propagate that change, make the intersect() method always return the result object at its end and change the statement at the start of the code to

ir = root.intersect(ray, ir);

and correct the typo in the following if statement (it is ir.material, not r.material).

PNS
  • 19,295
  • 32
  • 96
  • 143