Search in sources :

Example 26 with Point3

use of org.sunflow.math.Point3 in project joons-renderer by joonhyublee.

the class Sphere method prepareShadingState.

@Override
public void prepareShadingState(ShadingState state) {
    state.init();
    state.getRay().getPoint(state.getPoint());
    Instance parent = state.getInstance();
    Point3 localPoint = state.transformWorldToObject(state.getPoint());
    state.getNormal().set(localPoint.x, localPoint.y, localPoint.z);
    state.getNormal().normalize();
    float phi = (float) Math.atan2(state.getNormal().y, state.getNormal().x);
    if (phi < 0) {
        phi += 2 * Math.PI;
    }
    float theta = (float) Math.acos(state.getNormal().z);
    state.getUV().y = theta / (float) Math.PI;
    state.getUV().x = phi / (float) (2 * Math.PI);
    Vector3 v = new Vector3();
    v.x = -2 * (float) Math.PI * state.getNormal().y;
    v.y = 2 * (float) Math.PI * state.getNormal().x;
    v.z = 0;
    state.setShader(parent.getShader(0));
    state.setModifier(parent.getModifier(0));
    // into world space
    Vector3 worldNormal = state.transformNormalObjectToWorld(state.getNormal());
    v = state.transformVectorObjectToWorld(v);
    state.getNormal().set(worldNormal);
    state.getNormal().normalize();
    state.getGeoNormal().set(state.getNormal());
    // compute basis in world space
    state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), v));
}
Also used : Point3(org.sunflow.math.Point3) Instance(org.sunflow.core.Instance) Vector3(org.sunflow.math.Vector3)

Example 27 with Point3

use of org.sunflow.math.Point3 in project joons-renderer by joonhyublee.

the class Torus method prepareShadingState.

public void prepareShadingState(ShadingState state) {
    state.init();
    state.getRay().getPoint(state.getPoint());
    Instance parent = state.getInstance();
    // get local point
    Point3 p = state.transformWorldToObject(state.getPoint());
    // compute local normal
    float deriv = p.x * p.x + p.y * p.y + p.z * p.z - ri2 - ro2;
    state.getNormal().set(p.x * deriv, p.y * deriv, p.z * deriv + 2 * ro2 * p.z);
    state.getNormal().normalize();
    double phi = Math.asin(MathUtils.clamp(p.z / ri, -1, 1));
    double theta = Math.atan2(p.y, p.x);
    if (theta < 0) {
        theta += 2 * Math.PI;
    }
    state.getUV().x = (float) (theta / (2 * Math.PI));
    state.getUV().y = (float) ((phi + Math.PI / 2) / Math.PI);
    state.setShader(parent.getShader(0));
    state.setModifier(parent.getModifier(0));
    // into world space
    Vector3 worldNormal = state.transformNormalObjectToWorld(state.getNormal());
    state.getNormal().set(worldNormal);
    state.getNormal().normalize();
    state.getGeoNormal().set(state.getNormal());
    // make basis in world space
    state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
}
Also used : Point3(org.sunflow.math.Point3) Instance(org.sunflow.core.Instance) Vector3(org.sunflow.math.Vector3)

Example 28 with Point3

use of org.sunflow.math.Point3 in project joons-renderer by joonhyublee.

the class QuadMesh method prepareShadingState.

@Override
public void prepareShadingState(ShadingState state) {
    state.init();
    Instance parent = state.getInstance();
    int primID = state.getPrimitiveID();
    float u = state.getU();
    float v = state.getV();
    state.getRay().getPoint(state.getPoint());
    int quad = 4 * primID;
    int index0 = quads[quad + 0];
    int index1 = quads[quad + 1];
    int index2 = quads[quad + 2];
    int index3 = quads[quad + 3];
    Point3 v0p = getPoint(index0);
    Point3 v1p = getPoint(index1);
    Point3 v2p = getPoint(index2);
    Point3 v3p = getPoint(index2);
    float tanux = (1 - v) * (v1p.x - v0p.x) + v * (v2p.x - v3p.x);
    float tanuy = (1 - v) * (v1p.y - v0p.y) + v * (v2p.y - v3p.y);
    float tanuz = (1 - v) * (v1p.z - v0p.z) + v * (v2p.z - v3p.z);
    float tanvx = (1 - u) * (v3p.x - v0p.x) + u * (v2p.x - v1p.x);
    float tanvy = (1 - u) * (v3p.y - v0p.y) + u * (v2p.y - v1p.y);
    float tanvz = (1 - u) * (v3p.z - v0p.z) + u * (v2p.z - v1p.z);
    float nx = tanuy * tanvz - tanuz * tanvy;
    float ny = tanuz * tanvx - tanux * tanvz;
    float nz = tanux * tanvy - tanuy * tanvx;
    Vector3 ng = new Vector3(nx, ny, nz);
    ng = state.transformNormalObjectToWorld(ng);
    ng.normalize();
    state.getGeoNormal().set(ng);
    float k00 = (1 - u) * (1 - v);
    float k10 = u * (1 - v);
    float k01 = (1 - u) * v;
    float k11 = u * v;
    switch(normals.interp) {
        case NONE:
        case FACE:
            {
                state.getNormal().set(ng);
                break;
            }
        case VERTEX:
            {
                int i30 = 3 * index0;
                int i31 = 3 * index1;
                int i32 = 3 * index2;
                int i33 = 3 * index3;
                float[] normalsv = this.normals.data;
                state.getNormal().x = k00 * normalsv[i30 + 0] + k10 * normalsv[i31 + 0] + k11 * normalsv[i32 + 0] + k01 * normalsv[i33 + 0];
                state.getNormal().y = k00 * normalsv[i30 + 1] + k10 * normalsv[i31 + 1] + k11 * normalsv[i32 + 1] + k01 * normalsv[i33 + 1];
                state.getNormal().z = k00 * normalsv[i30 + 2] + k10 * normalsv[i31 + 2] + k11 * normalsv[i32 + 2] + k01 * normalsv[i33 + 2];
                state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
                state.getNormal().normalize();
                break;
            }
        case FACEVARYING:
            {
                int idx = 3 * quad;
                float[] normalsf = this.normals.data;
                state.getNormal().x = k00 * normalsf[idx + 0] + k10 * normalsf[idx + 3] + k11 * normalsf[idx + 6] + k01 * normalsf[idx + 9];
                state.getNormal().y = k00 * normalsf[idx + 1] + k10 * normalsf[idx + 4] + k11 * normalsf[idx + 7] + k01 * normalsf[idx + 10];
                state.getNormal().z = k00 * normalsf[idx + 2] + k10 * normalsf[idx + 5] + k11 * normalsf[idx + 8] + k01 * normalsf[idx + 11];
                state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
                state.getNormal().normalize();
                break;
            }
    }
    float uv00 = 0, uv01 = 0, uv10 = 0, uv11 = 0, uv20 = 0, uv21 = 0, uv30 = 0, uv31 = 0;
    switch(uvs.interp) {
        case NONE:
        case FACE:
            {
                state.getUV().x = 0;
                state.getUV().y = 0;
                break;
            }
        case VERTEX:
            {
                int i20 = 2 * index0;
                int i21 = 2 * index1;
                int i22 = 2 * index2;
                int i23 = 2 * index3;
                float[] uvsv = this.uvs.data;
                uv00 = uvsv[i20 + 0];
                uv01 = uvsv[i20 + 1];
                uv10 = uvsv[i21 + 0];
                uv11 = uvsv[i21 + 1];
                uv20 = uvsv[i22 + 0];
                uv21 = uvsv[i22 + 1];
                uv20 = uvsv[i23 + 0];
                uv21 = uvsv[i23 + 1];
                break;
            }
        case FACEVARYING:
            {
                int idx = quad << 1;
                float[] uvsf = this.uvs.data;
                uv00 = uvsf[idx + 0];
                uv01 = uvsf[idx + 1];
                uv10 = uvsf[idx + 2];
                uv11 = uvsf[idx + 3];
                uv20 = uvsf[idx + 4];
                uv21 = uvsf[idx + 5];
                uv30 = uvsf[idx + 6];
                uv31 = uvsf[idx + 7];
                break;
            }
    }
    if (uvs.interp != InterpolationType.NONE) {
        // get exact uv coords and compute tangent vectors
        state.getUV().x = k00 * uv00 + k10 * uv10 + k11 * uv20 + k01 * uv30;
        state.getUV().y = k00 * uv01 + k10 * uv11 + k11 * uv21 + k01 * uv31;
        float du1 = uv00 - uv20;
        float du2 = uv10 - uv20;
        float dv1 = uv01 - uv21;
        float dv2 = uv11 - uv21;
        Vector3 dp1 = Point3.sub(v0p, v2p, new Vector3()), dp2 = Point3.sub(v1p, v2p, new Vector3());
        float determinant = du1 * dv2 - dv1 * du2;
        if (determinant == 0.0f) {
            // create basis in world space
            state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
        } else {
            float invdet = 1.f / determinant;
            // Vector3 dpdu = new Vector3();
            // dpdu.x = (dv2 * dp1.x - dv1 * dp2.x) * invdet;
            // dpdu.y = (dv2 * dp1.y - dv1 * dp2.y) * invdet;
            // dpdu.z = (dv2 * dp1.z - dv1 * dp2.z) * invdet;
            Vector3 dpdv = new Vector3();
            dpdv.x = (-du2 * dp1.x + du1 * dp2.x) * invdet;
            dpdv.y = (-du2 * dp1.y + du1 * dp2.y) * invdet;
            dpdv.z = (-du2 * dp1.z + du1 * dp2.z) * invdet;
            dpdv = state.transformVectorObjectToWorld(dpdv);
            // create basis in world space
            state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), dpdv));
        }
    } else {
        state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
    }
    int shaderIndex = faceShaders == null ? 0 : (faceShaders[primID] & 0xFF);
    state.setShader(parent.getShader(shaderIndex));
    state.setModifier(parent.getModifier(shaderIndex));
}
Also used : Point3(org.sunflow.math.Point3) Instance(org.sunflow.core.Instance) Vector3(org.sunflow.math.Vector3)

Example 29 with Point3

use of org.sunflow.math.Point3 in project joons-renderer by joonhyublee.

the class SphereFlake method prepareShadingState.

public void prepareShadingState(ShadingState state) {
    state.init();
    state.getRay().getPoint(state.getPoint());
    Instance parent = state.getInstance();
    Point3 localPoint = state.transformWorldToObject(state.getPoint());
    float cx = state.getU();
    float cy = state.getV();
    float cz = state.getW();
    state.getNormal().set(localPoint.x - cx, localPoint.y - cy, localPoint.z - cz);
    state.getNormal().normalize();
    float phi = (float) Math.atan2(state.getNormal().y, state.getNormal().x);
    if (phi < 0) {
        phi += 2 * Math.PI;
    }
    float theta = (float) Math.acos(state.getNormal().z);
    state.getUV().y = theta / (float) Math.PI;
    state.getUV().x = phi / (float) (2 * Math.PI);
    Vector3 v = new Vector3();
    v.x = -2 * (float) Math.PI * state.getNormal().y;
    v.y = 2 * (float) Math.PI * state.getNormal().x;
    v.z = 0;
    state.setShader(parent.getShader(0));
    state.setModifier(parent.getModifier(0));
    // into world space
    Vector3 worldNormal = state.transformNormalObjectToWorld(state.getNormal());
    v = state.transformVectorObjectToWorld(v);
    state.getNormal().set(worldNormal);
    state.getNormal().normalize();
    state.getGeoNormal().set(state.getNormal());
    // compute basis in world space
    state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), v));
}
Also used : Point3(org.sunflow.math.Point3) Instance(org.sunflow.core.Instance) Vector3(org.sunflow.math.Vector3)

Example 30 with Point3

use of org.sunflow.math.Point3 in project joons-renderer by joonhyublee.

the class FileMesh method generate.

private TriangleMesh generate(int[] tris, float[] verts, boolean smoothNormals) {
    ParameterList pl = new ParameterList();
    pl.addIntegerArray("triangles", tris);
    pl.addPoints("points", InterpolationType.VERTEX, verts);
    if (smoothNormals) {
        // filled with 0's
        float[] normals = new float[verts.length];
        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]);
            // compute normal
            Point3.normal(p0, p1, p2, n);
            // 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", InterpolationType.VERTEX, normals);
    }
    TriangleMesh m = new TriangleMesh();
    if (m.update(pl, null)) {
        return m;
    }
    // printed by the mesh itself - no need to repeat it here
    return null;
}
Also used : Point3(org.sunflow.math.Point3) TriangleMesh(org.sunflow.core.primitive.TriangleMesh) ParameterList(org.sunflow.core.ParameterList) Vector3(org.sunflow.math.Vector3)

Aggregations

Point3 (org.sunflow.math.Point3)39 Vector3 (org.sunflow.math.Vector3)27 Instance (org.sunflow.core.Instance)9 Color (org.sunflow.image.Color)7 Ray (org.sunflow.core.Ray)5 LightSample (org.sunflow.core.LightSample)4 TriangleMesh (org.sunflow.core.primitive.TriangleMesh)3 ParameterList (org.sunflow.core.ParameterList)2 Matrix4 (org.sunflow.math.Matrix4)2 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 FloatBuffer (java.nio.FloatBuffer)1 MappedByteBuffer (java.nio.MappedByteBuffer)1 PrimitiveList (org.sunflow.core.PrimitiveList)1 SceneParser (org.sunflow.core.SceneParser)1 ShadingState (org.sunflow.core.ShadingState)1 QuadMesh (org.sunflow.core.primitive.QuadMesh)1 BoundingBox (org.sunflow.math.BoundingBox)1