/*********************************************************************** Persistence of Vision SDL include file Description: A macro to simulate lens movements in architectural scenes Helps prevent the "falling verticals syndrome" Author: John Guthkelch (Doctor John) William H. Walker (Bald Eagle) for Version 4.0 Version 3.0 Released May 2006 Version 4.0 Released November 2020 History: Version 4.0: 1. Removed apparently useless (?) y correction (VCorr) 2. Corrected unwanted camera translation for y>0.0. Version 3.0: 1. Removed necessity of passing parameters when calling macro. Less typing needed :-) 2. Added code so macro can be used when using right-handed coordinates (i.e. z-axis is up). Version 2.0: 1. Improved warning so that camera automatically reverts to default type if insane values are given for CamPos and/or CamLook 2. Corrected silly mathematical error in vertical scaling.This is now correct so switch has been taken out. Note: I have never tested the macro on any scenes in which the viewing axes are anything but either 'up y' or 'up z' so ymmv with your rotated camera. *********************************************************************** License & copyright: (c) 2006 John Guthkelch 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. (See http://www.gnu.org/licenses/gpl.txt for the full GPL text) ***********************************************************************/ #macro FieldCam() #local CD=CamLook-CamPos; #ifndef (Up_Z) #if (CD.x!=0 | CD.z!=0) // Note: That's a Boolean OR not an // uppercase i or a lowercase L! #local HypoXZ=sqrt(pow(CD.x, 2)+pow(CD.z, 2)); #local CosThetaX=CD.x/HypoXZ; #local CosThetaZ=CD.z/HypoXZ; #if (CD.x=0) #local ShearX=0; #else #local ShearX=(CD.y/CD.x)*pow(CosThetaX, 2); #end #if (CD.z=0) #local ShearZ=0; #else #local ShearZ=(CD.y/CD.z)*pow(CosThetaZ, 2); #end #declare NoFall=transform { matrix <1, 0, 0, ShearX, 1, ShearZ, 0, 0, 1, -CamPos.y*ShearX, 0, -CamPos.y*ShearZ> } #else #warning "Viewing vector is perpendicular to XZ-plane.\n" #warning "Camera changed to default type.\n" #declare NoFall=transform { matrix <1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0> } #end #else #if (CD.x!=0 | CD.y!=0) // Note: That's a Boolean OR not an // uppercase i or a lowercase L! #local HypoXY=sqrt(pow(CD.x, 2)+pow(CD.y, 2)); #local CosThetaX=CD.x/HypoXY; #local CosThetaY=CD.y/HypoXY; #if (CD.x=0) #local ShearX=0; #else #local ShearX=(CD.z/CD.x)*pow(CosThetaX, 2); #end #if (CD.y=0) #local ShearY=0; #else #local ShearY=(CD.z/CD.y)*pow(CosThetaY, 2); #end #declare NoFall=transform { matrix <1, 0, 0, 0, 1, 0, ShearX, ShearY, 1, -CamPos.z*ShearX, -CamPos.z*ShearY, 0> } #else #warning "Viewing vector is perpendicular to XY-plane.\n" #warning "Camera changed to default type.\n" #declare NoFall=transform { matrix <1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0> } #end #end #end /*****************USAGE1********************** #declare CamPos=;// Just replace with location vector #declare CamLook=; // -"- -"- with look_at vector [#declare Up_Z=1;] // Only use this #declare when using right-handed coordinates camera { FieldCam () perspective location CamPos [angle Whatever] // Not essential but can be used [right If_you_want] // Also not essential but can be used up y | up z //whichever you need transform {NoFall} look_at CamLook } *************USAGE 2********************** Don't forget to switch vista buffer off by putting Vista_Buffer=0 in your .ini file or using -uv on the command line. Note: As of version 3.7 the Vista_Buffer option has been deprecated. ******************************************************************/