Example #1
0
 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);
 }
Example #2
0
 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);
             }
         }
     }
 }
Example #3
0
 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;
 }
Example #4
0
        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;
        }
Example #5
0
        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++;

            }
        }
Example #6
0
 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]);
 }