POV-Ray : Newsgroups : povray.general : perspective user defined camera? : Re: perspective user defined camera? Server Time
26 May 2024 20:15:48 EDT (-0400)
  Re: perspective user defined camera?  
From: ingo
Date: 28 Jan 2019 12:40:23
Message: <XnsA9E5BDF46A3E4seed7@news.povray.org>
in news:web.5c4e6a2962f2921970c5131a0@news.povray.org Tor Olav
Kristensen wrote: 

> BTW:
> It would be nice if user defined cameras could be transformed
> directly like other cameras. E.g. like this:
> 

Thats what I thought too, but,

This morning after seeing your new code I made a laarge pot of strong 
coffee and started tinkering. It thought me where I went wrong on several 
occasions. 
I consistenly threw away X1_Y and X1_Z components in simmilar constructs 
;(
  #local vT1_X = vtransform(x, LookAtTransform);
  #local X1_X = vT1_X.x;
  #local X1_Y = vT1_X.y;
  #local X1_Z = vT1_X.z;

After getting more grip on your code I turned it in a macro and that adds 
flexibility you won't have with direct transforms.

This way you can spend your attention to the screen --> scene transfer 
and then just call the macro. It should work for most camera types.
I can also see it useful for setting up stereo cams, parallel or toed in. 
Or for greating images with insets where a small region of the image is 
rendered as a detail for a bigger scene.
I added it to a tile rendering camera without problem.
So, a lot of options to investigate 

ingo

very unfinished:
---%<------%<------%<---
#version 3.8;

global_settings { assumed_gamma 1.0 }

#include "colors.inc"
#include "transforms.inc"

#macro ucdPerspective(pLocation,pLookAt,Angle)
  #local D0_X_Fn = function(u, v) {u*image_width };
  #local D0_Y_Fn = function(u, v) {v*image_height};
  #local D0_Z_Fn = function(u, v) {image_width/2/tan(radians(Angle/2))};
  #local LocationX = pLocation.x;
  #local LocationY = pLocation.y;
  #local LocationZ = pLocation.z;
  #local(D1_X_Fn, D1_Y_Fn, D1_Z_Fn) = ucdLookAtTransform(
    D0_X_Fn,D0_Y_Fn,D0_Z_Fn,pLocation,pLookAt,Angle
  );
  camera {
    user_defined
    location {
      function { LocationX }
      function { LocationY }
      function { LocationZ }
    }
    direction {
    function { D1_X_Fn(u, v) }
    function { D1_Y_Fn(u, v) }
    function { D1_Z_Fn(u, v) }
    }
  }
#end

#macro ucdLookAtTransform(
  D0_X_Fn,D0_Y_Fn,D0_Z_Fn,pLocation,pLookAt,Angle
)
  #local vDirection_0 = +1*z;
  #local vRight_0 = +image_width/image_height*x;
  #local vUp_0 = +1*y;
//the three above should probably move to the cam definition
  #local vLookAt = pLookAt - pLocation;
  #local LookAtTransform = Reorient_Trans(z, vLookAt)
  #local vDirection_1 = vtransform(vDirection_0, LookAtTransform);
  #local vRight_1 = vtransform(vRight_0, LookAtTransform);
  #local vUp_1 = vtransform(vUp_0, LookAtTransform);
  #local vT1_X = vtransform(x, LookAtTransform);
  #local X1_X = vT1_X.x;
  #local X1_Y = vT1_X.y;
  #local X1_Z = vT1_X.z;
  #local vT1_Y = vtransform(y, LookAtTransform);
  #local Y1_X = vT1_Y.x;
  #local Y1_Y = vT1_Y.y;
  #local Y1_Z = vT1_Y.z;
  #local vT1_Z = vtransform(z, LookAtTransform);
  #local Z1_X = vT1_Z.x;
  #local Z1_Y = vT1_Z.y;
  #local Z1_Z = vT1_Z.z;
  #local D1_X_Fn =
      function(u, v) {
          0
          + X1_X*D0_X_Fn(u, v)
          + Y1_X*D0_Y_Fn(u, v)
          + Z1_X*D0_Z_Fn(u, v)
      }
  ;
  #local D1_Y_Fn =
      function(u, v) {
          0
          + X1_Y*D0_X_Fn(u, v)
          + Y1_Y*D0_Y_Fn(u, v)
          + Z1_Y*D0_Z_Fn(u, v)
      }
  ;
  #local D1_Z_Fn =
      function(u, v) {
          0
          + X1_Z*D0_X_Fn(u, v)
          + Y1_Z*D0_Y_Fn(u, v)
          + Z1_Z*D0_Z_Fn(u, v)
      }
  ;
  (D1_X_Fn, D1_Y_Fn, D1_Z_Fn)
#end

#declare pLocation = <0.0, 0.5, -0.0>;
#declare pLookAt = <0.0, 0.0, 1.0>;
#declare Angle = 90;

ucdPerspective(pLocation,pLookAt,Angle)

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#declare SphereRadius = 0.3;

sphere { < 0,  0,  2>, SphereRadius pigment { checker White Black } }
sphere { < 0,  0, -2>, SphereRadius pigment { checker White Red   } }
sphere { < 2,  0,  0>, SphereRadius pigment { checker White Green } }
sphere { <-2,  0,  0>, SphereRadius pigment { checker White Blue  } }

union {
    sphere { < 0,  0,  2>, SphereRadius pigment { White } }
    sphere { < 0,  0, -2>, SphereRadius pigment { Red   } }
    sphere { < 2,  0,  0>, SphereRadius pigment { Green } }
    sphere { <-2,  0,  0>, SphereRadius pigment { Blue  } }
    translate 0.5*y
}

background { color Gray80 }

light_source { <1, 1, -1>*100 White }
light_source { <0, 0, 0> Gray20 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

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