public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power) { p.set(lightPoint); float phi = (float)(2 * Math.PI * randX1); float s = (float)Math.Sqrt(randY1 * (1.0f - randY1)); dir.x = (float)Math.Cos(phi) * s; dir.y = (float)Math.Sin(phi) * s; dir.z = (float)(1 - 2 * randY1); power.set(this.power); }
public void getSamples(ShadingState state) { if (storedPhotons == 0) return; NearestPhotons np = new NearestPhotons(state.getPoint(), gatherNum, gatherRadius * gatherRadius); locatePhotons(np); if (np.found < 8) return; Point3 ppos = new Point3(); Vector3 pdir = new Vector3(); Vector3 pvec = new Vector3(); float invArea = 1.0f / ((float)Math.PI * np.dist2[0]); float maxNDist = np.dist2[0] * 0.05f; float f2r2 = 1.0f / (filterValue * filterValue * np.dist2[0]); float fInv = 1.0f / (1.0f - 2.0f / (3.0f * filterValue)); for (int i = 1; i <= np.found; i++) { Photon phot = np.index[i]; Vector3.decode(phot.dir, pdir); float cos = -Vector3.dot(pdir, state.getNormal()); if (cos > 0.001) { ppos.set(phot.x, phot.y, phot.z); Point3.sub(ppos, state.getPoint(), pvec); float pcos = Vector3.dot(pvec, state.getNormal()); if ((pcos < maxNDist) && (pcos > -maxNDist)) { LightSample sample = new LightSample(); sample.setShadowRay(new Ray(state.getPoint(), pdir.negate())); sample.setRadiance(new Color().setRGBE(np.index[i].power).mul(invArea / cos), Color.BLACK); sample.getDiffuseRadiance().mul((1.0f - (float)Math.Sqrt(np.dist2[i] * f2r2)) * fInv); state.addSample(sample); } } } }
private TriangleMesh generate(int[] tris, float[] verts, bool smoothNormals) { ParameterList pl = new ParameterList(); pl.addIntegerArray("triangles", tris); pl.addPoints("points", ParameterList.InterpolationType.VERTEX, verts); if (smoothNormals) { float[] normals = new float[verts.Length]; // filled with 0's Point3 p0 = new Point3(); Point3 p1 = new Point3(); Point3 p2 = new Point3(); Vector3 n = new Vector3(); for (int i3 = 0; i3 < tris.Length; i3 += 3) { int v0 = tris[i3 + 0]; int v1 = tris[i3 + 1]; int v2 = tris[i3 + 2]; p0.set(verts[3 * v0 + 0], verts[3 * v0 + 1], verts[3 * v0 + 2]); p1.set(verts[3 * v1 + 0], verts[3 * v1 + 1], verts[3 * v1 + 2]); p2.set(verts[3 * v2 + 0], verts[3 * v2 + 1], verts[3 * v2 + 2]); Point3.normal(p0, p1, p2, n); // compute normal // add face normal to each vertex // note that these are not normalized so this in fact weights // each normal by the area of the triangle normals[3 * v0 + 0] += n.x; normals[3 * v0 + 1] += n.y; normals[3 * v0 + 2] += n.z; normals[3 * v1 + 0] += n.x; normals[3 * v1 + 1] += n.y; normals[3 * v1 + 2] += n.z; normals[3 * v2 + 0] += n.x; normals[3 * v2 + 1] += n.y; normals[3 * v2 + 2] += n.z; } // normalize all the vectors for (int i3 = 0; i3 < normals.Length; i3 += 3) { n.set(normals[i3 + 0], normals[i3 + 1], normals[i3 + 2]); n.normalize(); normals[i3 + 0] = n.x; normals[i3 + 1] = n.y; normals[i3 + 2] = n.z; } pl.addVectors("normals", ParameterList.InterpolationType.VERTEX, normals); } TriangleMesh m = new TriangleMesh(); if (m.update(pl, null)) return m; // something failed in creating the mesh, the error message will be // printed by the mesh itself - no need to repeat it here return null; }
public void precomputeRadiance() { if (storedPhotons == 0) return; // precompute the radiance for all photons that are neither // leaves nor parents of leaves in the tree. int quadStoredPhotons = halfStoredPhotons / 2; Point3 p = new Point3(); Vector3 n = new Vector3(); Point3 ppos = new Point3(); Vector3 pdir = new Vector3(); Vector3 pvec = new Vector3(); Color irr = new Color(); Color pow = new Color(); float maxDist2 = gatherRadius * gatherRadius; NearestPhotons np = new NearestPhotons(p, numGather, maxDist2); Photon[] temp = new Photon[quadStoredPhotons + 1]; UI.taskStart("Precomputing radiance", 1, quadStoredPhotons); for (int i = 1; i <= quadStoredPhotons; i++) { UI.taskUpdate(i); Photon curr = photons[i]; p.set(curr.x, curr.y, curr.z); Vector3.decode(curr.normal, n); irr.set(Color.BLACK); np.reset(p, maxDist2); locatePhotons(np); if (np.found < 8) { curr.data = 0; temp[i] = curr; continue; } float invArea = 1.0f / ((float)Math.PI * np.dist2[0]); float maxNDist = np.dist2[0] * 0.05f; for (int j = 1; j <= np.found; j++) { Photon phot = np.index[j]; Vector3.decode(phot.dir, pdir); float cos = -Vector3.dot(pdir, n); if (cos > 0.01f) { ppos.set(phot.x, phot.y, phot.z); Point3.sub(ppos, p, pvec); float pcos = Vector3.dot(pvec, n); if ((pcos < maxNDist) && (pcos > -maxNDist)) irr.add(pow.setRGBE(phot.power)); } } irr.mul(invArea); // compute radiance irr.mul(new Color(curr.data)).mul(1.0f / (float)Math.PI); curr.data = irr.toRGBE(); temp[i] = curr; } UI.taskStop(); // resize photon map to only include irradiance photons numGather /= 4; maxRadius = 1.4f * (float)Math.Sqrt(maxPower * numGather); if (gatherRadius > maxRadius) gatherRadius = maxRadius; storedPhotons = quadStoredPhotons; halfStoredPhotons = storedPhotons / 2; log2n = (int)Math.Ceiling(Math.Log(storedPhotons) / Math.Log(2.0)); photons = temp; hasRadiance = true; }
private void GenerateMesh() { List<Vector3> curvePoints = new List<Vector3>(); List<Vector3> attractorPoints = new List<Vector3>(); pipeFunction.InitParameters(); attractorPoints.Capacity = pipeSegments + 2; curvePoints.Capacity = (pipeSegments + 2) * 5; int circleSegments = outlinePoints.Count; float tDelta = 1.0f/(knotsPerPipeSegment-1); attractorPoints.Add(startPosition); Vector3 temp = new Vector3(); temp.set(startPosition); // Console.WriteLine(temp); for (int i =0; i<pipeSegments; i++) { pipeFunction.GetNextPosition(temp); Vector3 nextPoint = new Vector3(); nextPoint.set(temp); attractorPoints.Add(nextPoint); } // special case the first point int lastItem = attractorPoints.Count-1; if (attractorPoints[0] == attractorPoints[lastItem]) { // it loops attractorPoints.RemoveAt(lastItem); Vector3 tmp = attractorPoints[ attractorPoints.Count-1]; attractorPoints.Add(attractorPoints[0]); attractorPoints.Insert(0, tmp); } else { // it does not loop Vector3 diff= new Vector3(); diff = Vector3.sub(attractorPoints[0], attractorPoints[1], diff); diff = Vector3.add(attractorPoints[0], diff, diff); Vector3 diff2 = new Vector3(); diff2 = Vector3.sub(attractorPoints[lastItem], attractorPoints[lastItem-1], diff2); diff2 = Vector3.add(attractorPoints[lastItem], diff2, diff2); attractorPoints.Add(diff2); attractorPoints.Insert(0,diff ); } // Console.WriteLine("attractorPoints: {0}" , attractorPoints.Count); int knotIndex = 0; Vector3 splinePoint = new Vector3(); Vector3 tangent = new Vector3(); Vector3 normal = new Vector3(); Vector3 up = new Vector3(0f,1f,0f); Point3 zero = new Point3(0f,0f,0f); Point3 tangentAsPoint = new Point3(); Point3 rotatedPoint = new Point3(); Vector3 oldSplinePoint = new Vector3(); Matrix4 rotateToTangent ; int pipeIndex = 0; int quadIndex = 0; int circleIndex = 0; int normalIndex = 0; float t=0f; foreach ( Vector3 tempv in attractorPoints) { tempv.mul(4.0f); // Console.WriteLine("attractorPoint: {0}" , tempv); } oldSplinePoint.set(attractorPoints[0]); for (int i=0; i<=pipeSegments-1; i++) { while (t <= 1.0f) { // Console.WriteLine("t : {0}", t); // Console.WriteLine("knotIndex : {0} - {1}", knotIndex, knotIndex+3); // Console.WriteLine(attractorPoints[knotIndex+1]); // Console.WriteLine(attractorPoints[knotIndex+2]); splinePoint.x = CatmullRomSpline(t, attractorPoints[knotIndex].x, attractorPoints[knotIndex+1].x, attractorPoints[knotIndex+2].x, attractorPoints[knotIndex+3].x); splinePoint.y = CatmullRomSpline(t, attractorPoints[knotIndex].y, attractorPoints[knotIndex+1].y, attractorPoints[knotIndex+2].y, attractorPoints[knotIndex+3].y); splinePoint.z = CatmullRomSpline(t, attractorPoints[knotIndex].z, attractorPoints[knotIndex+1].z, attractorPoints[knotIndex+2].z, attractorPoints[knotIndex+3].z); t += tDelta; tangent = Vector3.sub(splinePoint, oldSplinePoint, tangent).normalize(); tangentAsPoint.set(tangent.x, tangent.y, tangent.z); // normal = Vector3.cross(tangent,up,normal).normalize(); oldSplinePoint.set(splinePoint); // Matrix4 rotateAlongTangent = Matrix4.rotate(tangent.x, tangent.y, tangent.z, (float)thetaDelta); rotateToTangent = Matrix4.lookAt(zero, tangentAsPoint, up);//.inverse(); if(circleIndex == 0) { for (int circleSegement = 0; circleSegement < circleSegments ; circleSegement++) { // pointOnOutline.set (pipeRadius * (float)Math.Cos(theta) ,pipeRadius * (float)Math.Sin(theta), 0f); rotatedPoint = rotateToTangent.transformP(outlinePoints[circleSegement]); bb.include(rotatedPoint.x + splinePoint.x, rotatedPoint.y + splinePoint.y, rotatedPoint.z + splinePoint.z); points[pipeIndex++] = rotatedPoint.x + splinePoint.x; points[pipeIndex++] = rotatedPoint.y + splinePoint.y; points[pipeIndex++] = rotatedPoint.z + splinePoint.z; if(smooth) { normal.x = rotatedPoint.x; normal.y = rotatedPoint.y; normal.z = rotatedPoint.z; normal.normalize(); normals.data[normalIndex++] = normal.x; normals.data[normalIndex++] = normal.y; normals.data[normalIndex++] = normal.z; } } } else { // go round it a circle. int circleSegement; for (circleSegement = 0; circleSegement < circleSegments; circleSegement++) { rotatedPoint = rotateToTangent.transformP(outlinePoints[circleSegement]); bb.include(rotatedPoint.x + splinePoint.x, rotatedPoint.y + splinePoint.y, rotatedPoint.z + splinePoint.z); points[pipeIndex++] = rotatedPoint.x + splinePoint.x; points[pipeIndex++] = rotatedPoint.y + splinePoint.y; points[pipeIndex++] = rotatedPoint.z + splinePoint.z; if(smooth) { normal.x = rotatedPoint.x; normal.y = rotatedPoint.y; normal.z = rotatedPoint.z; normal.normalize(); normals.data[normalIndex++] = normal.x; normals.data[normalIndex++] = normal.y; normals.data[normalIndex++] = normal.z; } if (circleSegement + 1 < circleSegments) { // Console.WriteLine("quadIndex : {0}", quadIndex); quads[quadIndex++] = circleSegement + ((circleIndex - 1) * circleSegments) ; quads[quadIndex++] = circleSegement + ((circleIndex - 1) * circleSegments) + 1; quads[quadIndex++] = circleSegement + (circleIndex * circleSegments) + 1; quads[quadIndex++] = circleSegement + (circleIndex * circleSegments); } } // joint it back to first points quads[quadIndex++] = (circleSegement - 1) + ((circleIndex - 1) * circleSegments) ; quads[quadIndex++] = ((circleIndex - 1) * circleSegments); quads[quadIndex++] = (circleIndex * circleSegments) ; quads[quadIndex++] = (circleSegement - 1) + (circleIndex * circleSegments); } circleIndex++; } t = tDelta; knotIndex++; } }
public void getPoint(int tri, int i, Point3 p) { int index = 3 * triangles[3 * tri + i]; p.set(points[index], points[index + 1], points[index + 2]); }