/** * @(#) $RCSfile: SimpleCameraLoop.as,v $ $Revision: 1.3 $ $Date: 2003/01/29 16:40:19 $ * * Copyright 2003 Orgdot AS. All Rights Reserved. * http://dev.swfit.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * A simple interactive camera model - based on projection (rotation and scale) * of flash movie clips. Rules: The camera back wall is circular and always * perpendicular to the focal point. The centers of the movie clips are projected * through the focal point. For ease of computation / orientation we let the clips * exist on the same side of the focal point as the camera back wall. * * The unrotated xy-coordinates are determined from where they hit the camera wall, * and then rotated. If they do not hit the camera back wall, they are set invisible. * The distance from the focal point determines the scale (and / or alpha) of the * movie clips. The rotation of the movie clips is the opposite of the camera. See * MouseEngineLoop for details on camera x, y, z, rotation etc. * * @author Olaf Havnes * @version $Revision: 1.3 $ $Date: 2003/01/29 16:40:19 $ * @since SWFIT1.0 */ /** * To start with we have a vector in space Pn = (xp, yp, zp) and a vector C (stored in * _level0) representing the normal of the camera back wall. */ // Get the squared length. p_len_sq = xp * xp + yp * yp + zp * zp; // The change should not be so dramatic as to make this very wrong // NB! Remember to supply an initial p_len! p_len = (p_len + p_len_sq / p_len) / 2; // Compute the dot product : p_dot_c = xp * /:camera_x + yp * /:camera_y + zp * /:camera_z; // Is the particle on the correct side of the focal point? if (p_dot_c > 0) { // intersection test: cos (A) > cos (Amax), and p_dot_c = |C| * |P| * cos (A) // we have stored some precomputed values at _level0: if (p_dot_c * p_dot_c > p_len_sq * /:cisect) { // show this clip _visible = true; // to find the intersection point we scale the vector P: // Pt = t * P, so that Pt touches the back wall. Then (Pt - C).C = 0, // or t = C.C / P.C = |C|^2 / P.C t = /:cam_len_sq / p_dot_c; x_tp = t * xp - /:camera_x; y_tp = t * yp - /:camera_y; z_tp = t * zp - /:camera_z; // project this vector onto the "rotated horizon unit vector" of the camera back wall xd = x_tp * /:huv_x + y_tp * /:huv_y + z_tp * /:huv_z; // project this vector onto the "rotated verizon unit vector" of the camera back wall yd = x_tp * /:vuv_x + y_tp * /:vuv_y + z_tp * /:vuv_z; } else { _visible = false; } } else { // kill the particle ? reset = true; }