package jembench.parallel.raytrace; import java.util.Vector; public class Ray{ public static double[] intersect(Sphere s, double[] rayPos, double[] rayDir, double dov, double[] tmp_1, double[][]tmp_3, double[][]tmp_6){ double[] result = tmp_6[0]; result[0] = -1; double[] c = tmp_3[2]; c = s.position; double[] p0_sub_c = tmp_3[3]; p0_sub_c[0] = rayPos[0]-c[0]; p0_sub_c[1] = rayPos[1]-c[1]; p0_sub_c[2] = rayPos[2]-c[2]; double ra = tmp_1[1]; ra = s.radius; double A = tmp_1[2]; double B = tmp_1[3]; double C = tmp_1[4]; double D = tmp_1[5]; double t1 = tmp_1[1]; double t2 = tmp_1[1]; A = rayDir[0]*rayDir[0] + rayDir[1]*rayDir[1] + rayDir[2]*rayDir[2]; B = 2 * (rayDir[0]*p0_sub_c[0] + rayDir[1]*p0_sub_c[1] + rayDir[2]*p0_sub_c[2]); C = (p0_sub_c[0]*p0_sub_c[0] + p0_sub_c[1]*p0_sub_c[1] + p0_sub_c[2]*p0_sub_c[2]) - ra*ra; D = B*B - 4*A*C; t1=-1; t2=-1; if(D < 0){//Kein Schnittpunkt t1=-1; } if(D == 0){//Ein Schnittpunkt t1 = ( -B - Math.sqrt(D)) / (2.0 * A); } if(D > 0){//2 Schnittpunkte t1 = (-B - Math.sqrt(D))/(2.0*A); t2 = (-B + Math.sqrt(D))/(2.0*A); if(t2 < t1 && t2 > 0) t1=t2; } if((result[0] < 0 && t1 > 0 && t1 < dov) || (t1 < result[0] && t1 > 0 && t1 < dov)){ result[0] = t1; result[1] = s.rgb[0]; result[2] = s.rgb[1]; result[3] = s.rgb[2]; return result; } result[0] = -1; return result; } public static double[] intersect(Vector sceneObjects, double[] rayPosition, double[] rayDirection, double dov, double[] tmp_1, double[][]tmp_3, double[][]tmp_6, int numRecursions){ double[]rayPos = rayPosition; double[]rayDir = rayDirection; double[]resultTmp = tmp_6[0]; double[]result = new double[6]; double[]result2= new double[6]; double ref=0; result[0] = -1; Object nearestObject = null; // for(Object o:sceneObjects) { for (int i=0; i<sceneObjects.size(); ++i) { Object o = sceneObjects.elementAt(i); if(o instanceof Sphere) resultTmp = intersect((Sphere)o, rayPos, rayDir, dov, tmp_1, tmp_3, tmp_6); else if(o instanceof Tri) resultTmp = intersect((Tri)o, rayPos, rayDir, dov, tmp_1, tmp_3, tmp_6); if(resultTmp[0] != -1){//Treffer ? if((resultTmp[0]>0 && resultTmp[0] < result[0]) || (resultTmp[0]>0 && result[0] <= 0)){ //n�hester Treffer ? nearestObject = o; ref = 0; if(o instanceof Sphere) ref = ((Sphere)o).reflection; else if(o instanceof Tri) ref = ((Tri)o).reflection; result[0] = resultTmp[0]; result[1] = (int)((1-ref)*resultTmp[1]); result[2] = (int)((1-ref)*resultTmp[2]); result[3] = (int)((1-ref)*resultTmp[3]); } } } if(numRecursions>0 && nearestObject!=null){ double[] refPos = new double[3]; double[] refDir = new double[3]; MyVector.scale(refPos, rayDir, result[0]-0.001);//Reflektionsort bestimmen MyVector.add(refPos, refPos, rayPos); if(nearestObject instanceof Sphere) refDir = ((Sphere)nearestObject).reflect(rayPos, rayDir);//Reflektionsrichtung bestimmen else if(nearestObject instanceof Tri) refDir = ((Tri)nearestObject).reflect(rayPos, rayDir);//Reflektionsrichtung bestimmen result2 = intersect(sceneObjects, refPos, refDir, dov, tmp_1, tmp_3, tmp_6, numRecursions-1); if(result2[0]>0){ result[1] += (int)((ref)*result2[1]); result[2] += (int)((ref)*result2[2]); result[3] += (int)((ref)*result2[3]); } } return result; } public static double[] intersect(Tri tri, double[] rayPos, double[]rayDir, double dov, double[] tmp_1, double[][]tmp_3, double[][]tmp_6){ double[] result = tmp_6[0]; double[] pl = tmp_6[0]; double[] lb = tmp_3[2]; double[] tmp1 = tmp_3[3]; double[] tmp2 = tmp_3[4]; double t = tmp_1[0]; //Schneidet der Strahl die Ebene des Dreiecks ? tri.getPlane(pl, tmp_3[2], tmp_3[3], tmp_3[4]); MyVector.add(lb, rayPos, rayDir); MyVector.scale(tmp1,pl,-1); double d = tmp_1[1]; d = tmp1[0]*pl[3] + tmp1[1]*pl[4] + tmp1[2]*pl[5]; MyVector.sub(tmp1,lb,rayPos); double D = tmp_1[2]; D = tmp1[0]*pl[3] + tmp1[1]*pl[4] + tmp1[2]*pl[5]; //MyVector wegmachen! if(D!=0){//Strahl schneidet die Dreiecksebene: t = (-d-(rayPos[0]*pl[3]+rayPos[1]*pl[4]+rayPos[2]*pl[5]))/D; double[]v = tmp_3[5]; MyVector.scale(v, rayDir, t); MyVector.add(v,v,rayPos); MyVector.sub(tmp1,v,tri.a); MyVector.sub(tmp2, tri.b, tri.a); double[] avXab = tmp_3[6]; MyVector.crossProd(avXab, tmp1, tmp2); MyVector.sub(tmp1,v,tri.b); MyVector.sub(tmp2,tri.c,tri.b); double[] bvXbc = tmp_3[7]; MyVector.crossProd(bvXbc, tmp1, tmp2); MyVector.sub(tmp1,v,tri.c); MyVector.sub(tmp2,tri.a,tri.c); double[] cvXca = tmp_3[8]; MyVector.crossProd(cvXca, tmp1, tmp2); //Zeigen alle in die selbe Richtung ? == Liegt der Schnittpunkt im Dreieck ? if(MyVector.sign(avXab, bvXbc) && MyVector.sign(bvXbc, cvXca)){ result[0] = t; result[1] = tri.rgb[0]; result[2] = tri.rgb[1]; result[3] = tri.rgb[2]; return result; } } result[0] = -1; return result; } }