POV-Ray : Newsgroups : povray.advanced-users : Different camera parameters : Re: Different camera parameters Server Time
29 Jul 2024 08:18:18 EDT (-0400)
  Re: Different camera parameters  
From: Philippe Debar
Date: 1 May 2003 09:52:52
Message: <3eb126b4@news.povray.org>
Thorsten Froehlich wrote:
> No, the source code is really much more correct.  You cannot come to a
> working reproduction of what happens without taking it from the source code.
> And no knowledge about parsers is required to understand it.  Only a tiny
> bit of C.

OK, I got back to Parse_Camera, gritted my teeth and tried to translate 
the look_at mechanism for perspective camera to POV's SDL. I think I 
succeeded ;-) Here's the code (more rants after that) :

// --- BEGIN SDL ---

// Reproducing POV original sky/look_at behavior in SDL
// for perspective camera only
camera{

   #local Cam_location  = 1*<0,.1,-3> ;
   #local Cam_direction = 1*vnormalize(<0,0,1>) ;
   #local Cam_up        = 1*vnormalize(<0,1,0>) ;
   #local Cam_right     = 1*vnormalize(<1,0,0>) ;
   #local Cam_sky       = 1*vnormalize(<0,1,0>) ;
   #local Cam_look_at   = <-.5,1,.5> ;
   //#local Cam_angle     = 30;

   #local Simulate_POV_look_at = on ;


   #if (Simulate_POV_look_at)

     #ifndef(Cam_location ) #declare Cam_location  = 0      ; #end
     #ifndef(Cam_direction) #declare Cam_direction = z      ; #end
     #ifndef(Cam_right    ) #declare Cam_right     = 1.33*x ; #end
     #ifndef(Cam_up       ) #declare Cam_up        = y      ; #end
     #ifndef(Cam_sky      ) #declare Cam_sky       = y      ; #end

     #ifdef(Cam_angle)
       #if(Cam_angle>=180) #error "Viewing angle has to be smaller than 
180 degrees." #end
       #if(Cam_angle<0) #error "Negative viewing angle." #end
       #declare Cam_direction = 
vnormalize(Cam_direction)*vlength(Cam_right)/ tan(Cam_angle*pi/360)/2;
     #end

     #ifdef(Cam_look_at)
       #declare Cam_direction_length = vlength(Cam_direction) ;
       #declare Cam_up_length = vlength(Cam_up) ;
       #declare Cam_right_length = vlength(Cam_right) ;
       #declare Cam_tempv = vcross(Cam_up, Cam_direction) ;
       #declare Cam_Handedness = vdot(Cam_tempv, Cam_right) ;

       #declare Cam_direction=Cam_look_at-Cam_location ;
       #if(vlength(Cam_direction)<1e-10) #error "Camera location and 
look_at point must be different." #end
       #declare Cam_direction=vnormalize(Cam_direction) ;

       #declare Cam_tempv= vcross(Cam_sky, Cam_direction) ;
       #if (vlength(Cam_tempv)>1e-10) #declare 
Cam_right=vnormalize(Cam_tempv) ; #end

       #declare Cam_up=vcross(Cam_direction, Cam_right)* Cam_up_length; 
// works bcs right and direction are normalized
       #declare Cam_direction=Cam_direction*Cam_direction_length ;
       #declare Cam_right = Cam_right * ( Cam_Handedness >0 ? 
Cam_right_length : -Cam_right_length ) ;
     #end
   #end


   #ifdef(Cam_location ) location  Cam_location  #end
   #ifdef(Cam_direction) direction Cam_direction #end
   #ifdef(Cam_right    ) up        Cam_up        #end
   #ifdef(Cam_up       ) right     Cam_right     #end
   #ifdef(Cam_sky      ) sky       Cam_sky       #end
   #ifdef(Cam_angle    ) angle     Cam_angle     #end
   #ifdef(Cam_look_at  ) look_at   Cam_look_at   #end

}

// --- END SDL ---


I adapted some of it to my taste, I hope I did not fucked anything up.

BTW, I found that POV produces not-very-helpful errors if one uses either :
* right 0
* up 0
* direction 0
The error is "Slab Building Error: Singular matrix in MInvers."

If you specify either
* sky 0
* sky = look_at - location

& use look_at
& you have vista buffers enabled (default), you'll get an somehow 
erroneous error : "Slab Building Error: Cannot use non-perpendicular 
camera vectors with vista buffer." - what happens is that the right 
vector can't be computed so is left with its original value, while 
direction and up are modified, effectively defining a sheared camera 
inside POV while the user never specified such a thing.

What I do not understand is that while I can get this behavior by using 
sky = look_at - location, I am unable to reproduce it using look_at = 
sky + location, which I deem much more probable to happen in real use.


Anyway, I hope the code can help people understand how the perspective 
camera's look_at is working. (BTW it seems to be 3.5 specific, but that 
is not documented in "2.6.14  Changed features that may 'break' old 
scenes").


Povingly,

Philippe


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.