/** * Creates the unit normal to the polygon by taking the cross product of the first two edges. * Call with 'nsides' set to two if the polygon is visible from both sides. */ void setNormal() { // We need three points to define two edges. if (n < 3) return; if (normal == null) normal = new float[3]; float[] p0 = {ps[points[0]], ps[points[0] + 1], ps[points[0] + 2]}; float[] p1 = {ps[points[1]], ps[points[1] + 1], ps[points[1] + 2]}; float[] p2 = {ps[points[2]], ps[points[2] + 1], ps[points[2] + 2]}; float[] e1 = new float[3]; float[] e2 = new float[3]; Tools3d.subtract(p1, p0, e1); Tools3d.subtract(p2, p1, e2); Tools3d.cross(e1, e2, normal); Tools3d.makeUnit(normal); dirtyNormal = false; }
/** * Decides if this polygon is a 'back face'. A back face is a polygon that is facing away from * the camera and therefore should not be drawn. If this polygon is double sided then it can not * be a back face. In such a case this routine has the side effect of ensuring that the normal * points towards the camera eye rather than away from it. * * @see Obj3d#draw(Graphics) */ boolean isBackFace(final float[] eye) { if (dirtyNormal) { setNormal(); } p[0] = ps[points[0]]; p[1] = ps[points[0] + 1]; p[2] = ps[points[0] + 2]; Tools3d.subtract(p, eye, ray); if (doubleSided) { // flip the normal if necessary so this is NOT a backface if (Tools3d.dot(normal, ray) >= 0) { Tools3d.scaleBy(normal, -1); } return false; } else { return (Tools3d.dot(normal, ray) >= 0); } }