|
![](/i/fill.gif) |
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
|
![](/i/fill.gif) |