Package jpbrt.shapes

Source Code of jpbrt.shapes.Triangle

package jpbrt.shapes;

import jpbrt.core.BBox;
import jpbrt.core.DifferentialGeometry;
import jpbrt.core.Global;
import jpbrt.core.Intersection;
import jpbrt.core.Normal;
import jpbrt.core.Point;
import jpbrt.core.Ray;
import jpbrt.core.Shape;
import jpbrt.core.Transform;
import jpbrt.core.Vector;

public class Triangle extends Shape
{
    private TriangleMesh mesh;
    private int v1, v2, v3;
   
    public Triangle(Transform o2w, Transform w2o, boolean ro,
        TriangleMesh mesh, int idx)
    {
        super(o2w, w2o, ro);
        this.mesh = mesh;
        this.v1 = mesh.vertexIndices[idx];
        this.v2 = mesh.vertexIndices[idx+1];
        this.v3 = mesh.vertexIndices[idx+2];
    }

    @Override
    public BBox objectBound()
    {
        Point p1 = mesh.p[v1];
        Point p2 = mesh.p[v2];
        Point p3 = mesh.p[v3];
        BBox bbox = new BBox( worldToObject.transform(p1), worldToObject.transform(p2) );
        return bbox.unionLocal( worldToObject.transform(p3) );
    }

    @Override
    public BBox worldBound()
    {
        Point p1 = mesh.p[v1];
        Point p2 = mesh.p[v2];
        Point p3 = mesh.p[v3];
        BBox bbox = new BBox(p1, p2);
        return bbox.unionLocal(p3);
    }
   
    @Override
    public Intersection intersect(Ray ray)
    {
        Intersection result = new Intersection();
       
        // compute s1 = d x e2
        Point p1 = mesh.p[v1];
        Point p2 = mesh.p[v2];
        Point p3 = mesh.p[v3];
        Vector e1 = p1.to(p2);
        Vector e2 = p1.to(p3);
        Vector s1 = ray.d.cross(e2);
        double divisor = s1.dot(e1);
        if (divisor == 0)
            return result;
        double invDivisor = 1.0 / divisor;
       
        // compute first barycentric coordinate b1
        Vector d = p1.to(ray.o);
        double b1 = d.dot(s1) * invDivisor;
        if (b1 < 0 || b1 > 1)
            return result;
       
        // compute second barycentric coordinate b2
        Vector s2 = d.cross(e1);
        double b2 = ray.d.dot(s2) * invDivisor;
        if (b2 < 0 || b2 > 1)
            return result;
       
        // compute t to intersection point
        double t = e2.dot(s2) * invDivisor;
        if (t < ray.mint || t > ray.maxt)
            return result;
       
        // compute triangle partial derivatives
        Vector dpdu, dpdv;
        double[][] uvs = getUVs();
       
        // compute deltas for triangle partial derivatives
        double du1 = uvs[0][0] - uvs[2][0];
        double du2 = uvs[1][0] - uvs[2][0];
        double dv1 = uvs[0][1] - uvs[2][1];
        double dv2 = uvs[1][1] - uvs[2][1];
        Vector dp1 = p3.to(p1);
        Vector dp2 = p3.to(p2);
       
        double determinant = du1 * dv2 - dv1 * du2;
        if (determinant == 0)
        {
            dpdu = new Vector();
            dpdv = new Vector();
            Global.coordinateSystem(e2.cross(e1).normalizeLocal(), dpdu, dpdv);
        }
        else
        {
            double invdet = 1.0 / determinant;
            dpdu = dp1.mul(dv2).sub(dp2.mul(dv1)).mulLocal(invdet);
            dpdv = dp2.mul(du1).sub(dp1.mul(du2)).mulLocal(invdet);
        }
       
        // interpolate (u, v) triangle parametric coordinates
        double b0 = 1 - b1 - b2;
        double tu = b0 * uvs[0][0] + b1 * uvs[1][0] + b2 * uvs[2][0];
        double tv = b0 * uvs[0][1] + b1 * uvs[1][1] + b2 * uvs[2][1];
       
        // test intersection against alpha texture, if present
        if (mesh.alphaTex != null)
        {
            Normal zeroN = new Normal(0, 0, 0);
            DifferentialGeometry dgLocal = new DifferentialGeometry(ray.eval(t), dpdu, dpdv, zeroN, zeroN, tu, tv, this);
            if (mesh.alphaTex.evaluate(dgLocal) == 0)
                return result;
        }
       
        // fill in DifferetialGeometry from triangle hit
        Normal zeroN = new Normal(0, 0, 0);
        DifferentialGeometry dg = new DifferentialGeometry(ray.eval(t), dpdu, dpdv, zeroN, zeroN, tu, tv, this);
       
        result.dg = dg;
        result.tHit = t;
        result.rayEpsilon = 1e-3 * t;
        result.hit = true;
        return result;
    }
   
    @Override
    public boolean intersectP(Ray ray)
    {
        // TODO can be faster
        return intersect(ray).hit;
    }
   
    @Override
    public double area()
    {
        Point p1 = mesh.p[v1];
        Point p2 = mesh.p[v2];
        Point p3 = mesh.p[v3];
        Vector v1 = p1.to(p2);
        Vector v2 = p1.to(p3);
        return 0.5 * v1.cross(v2).length();
    }
   
    @Override
    public DifferentialGeometry getShadingGeometry(Transform obj2World, DifferentialGeometry dg)
    {
        if (mesh.n == null && mesh.s == null)
            return dg;
       
        // TODO
        // initialize Triangle shading geometry with n and s
        // compute barycentric coordinates for point
       
        // use n and s to compute shading tangents for triangle, ss and ts
       
        return dg;
    }
   
    public double[][] getUVs()
    {
        double[][] uv = new double[3][2];
        if (mesh.uvs != null)
        {
            uv[0][0] = mesh.uvs[2 * v1];
            uv[0][1] = mesh.uvs[2 * v1 + 1];
            uv[1][0] = mesh.uvs[2 * v2];
            uv[1][1] = mesh.uvs[2 * v2 + 1];
            uv[2][0] = mesh.uvs[2 * v3];
            uv[2][1] = mesh.uvs[2 * v3 + 1];
        }
        else
        {
            uv[0][0] = 0; uv[0][1] = 0;
            uv[1][0] = 1; uv[1][1] = 0;
            uv[2][0] = 1; uv[2][1] = 1;
        }
        return uv;
    }
}
TOP

Related Classes of jpbrt.shapes.Triangle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.