Skip to content

Commit c5f8d78

Browse files
committed
Added function-based user-defined camera.
The syntax is `camera { user_defined location { FUNCTION_TRIPLET } direction { FUNCTION_TRIPLET } CAMERA_MODIFIERS }`. Instead of `{ FUNCTION_TRIPLET }`, a constant vector can be specified, and the usual defaults apply. Each `FUNCTION_TRIPLET` is a set of three functions, all taking as input parameters the image x and y position ranging from -0.5 (left/bottom) to +0.5 (right/top), and acting together to return a ray origin and direction for a given pixel. A direction of <0,0,0> indicates that the pixel is to be left black.
1 parent 9adacd7 commit c5f8d78

File tree

13 files changed

+268
-66
lines changed

13 files changed

+268
-66
lines changed

source/base/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#define OFFICIAL_VERSION_STRING "3.7.1"
4646
#define OFFICIAL_VERSION_NUMBER 371
4747

48-
#define POV_RAY_PRERELEASE "alpha.8508492"
48+
#define POV_RAY_PRERELEASE "alpha.8509766"
4949

5050
#if (POV_RAY_IS_AUTOBUILD == 1) && ((POV_RAY_IS_OFFICIAL == 1) || (POV_RAY_IS_SEMI_OFFICIAL == 1))
5151
#ifdef POV_RAY_PRERELEASE

source/core/coretypes.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,33 @@ class GenericCustomFunction
566566
virtual RETURN_T Execute(GenericFunctionContextPtr pContext) = 0;
567567
virtual GenericCustomFunction* Clone() const = 0;
568568
virtual const FunctionSourceInfo* GetSourceInfo() const { return NULL; }
569+
570+
template<typename T1>
571+
inline RETURN_T Execute(GenericFunctionContextPtr pContext, T1 arg1)
572+
{
573+
InitArguments(pContext);
574+
PushArgument(pContext, arg1);
575+
return Execute(pContext);
576+
}
577+
578+
template<typename T1, typename T2>
579+
inline RETURN_T Execute(GenericFunctionContextPtr pContext, T1 arg1, T2 arg2)
580+
{
581+
InitArguments(pContext);
582+
PushArgument(pContext, arg1);
583+
PushArgument(pContext, arg2);
584+
return Execute(pContext);
585+
}
586+
587+
template<typename T1, typename T2, typename T3>
588+
inline RETURN_T Execute(GenericFunctionContextPtr pContext, T1 arg1, T2 arg2, T3 arg3)
589+
{
590+
InitArguments(pContext);
591+
PushArgument(pContext, arg1);
592+
PushArgument(pContext, arg2);
593+
PushArgument(pContext, arg3);
594+
return Execute(pContext);
595+
}
569596
};
570597

571598
typedef GenericCustomFunction<double, double> GenericScalarFunction;

source/core/math/vector.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,16 @@ class GenericVector2d
307307
{
308308
return vect[X] * vect[X] + vect[Y] * vect[Y];
309309
}
310+
inline bool IsNull() const
311+
{
312+
return (vect[X] == 0.0) &&
313+
(vect[Y] == 0.0);
314+
}
315+
inline bool IsNearNull(T epsilon) const
316+
{
317+
return (abs(vect[X]) < epsilon) &&
318+
(abs(vect[Y]) < epsilon);
319+
}
310320
inline GenericVector2d normalized() const
311321
{
312322
T l = length();
@@ -522,6 +532,18 @@ class GenericVector3d
522532
{
523533
return vect[X] * vect[X] + vect[Y] * vect[Y] + vect[Z] * vect[Z];
524534
}
535+
inline bool IsNull() const
536+
{
537+
return (vect[X] == 0.0) &&
538+
(vect[Y] == 0.0) &&
539+
(vect[Z] == 0.0);
540+
}
541+
inline bool IsNearNull(T epsilon) const
542+
{
543+
return (abs(vect[X]) < epsilon) &&
544+
(abs(vect[Y]) < epsilon) &&
545+
(abs(vect[Z]) < epsilon);
546+
}
525547
inline GenericVector3d normalized() const
526548
{
527549
T l = length();

source/core/render/tracepixel.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ TracePixel::TracePixel(shared_ptr<SceneData> sd, const Camera* cam, TraceThreadD
200200
focalBlurData(NULL),
201201
maxTraceLevel(mtl),
202202
adcBailout(adcb),
203-
pretrace(pt)
203+
pretrace(pt),
204+
mpFunctionContext(NULL)
204205
{
205206
SetupCamera((cam == NULL) ? sd->parsedCamera : *cam);
206207
}
@@ -209,6 +210,8 @@ TracePixel::~TracePixel()
209210
{
210211
if(focalBlurData != NULL)
211212
delete focalBlurData;
213+
if (mpFunctionContext != NULL)
214+
delete mpFunctionContext;
212215
}
213216

214217
void TracePixel::SetupCamera(const Camera& cam)
@@ -246,6 +249,10 @@ void TracePixel::SetupCamera(const Camera& cam)
246249
aspectRatio = cameraLengthRight / cameraLengthUp;
247250
normalise = true;
248251
break;
252+
case USER_DEFINED_CAMERA:
253+
normalise = true;
254+
mpFunctionContext = sceneData->functionContextFactory->CreateFunctionContext(threadData);
255+
break;
249256
default:
250257
aspectRatio = cameraLengthRight / cameraLengthUp;
251258
break;
@@ -846,6 +853,31 @@ bool TracePixel::CreateCameraRay(Ray& ray, DBL x, DBL y, DBL width, DBL height,
846853
}
847854
break;
848855

856+
case USER_DEFINED_CAMERA:
857+
// Convert the x coordinate to be a DBL from -0.5 to 0.5.
858+
x0 = x / width - 0.5;
859+
860+
// Convert the y coordinate to be a DBL from -0.5 to 0.5.
861+
y0 = 0.5 - y / height;
862+
863+
for (unsigned int i = 0; i < 3; ++i)
864+
{
865+
if (camera.Location_Fn[i] != NULL)
866+
cameraLocation[i] = camera.Location_Fn[i]->Execute(mpFunctionContext, x0, y0);
867+
if (camera.Direction_Fn[i] != NULL)
868+
cameraDirection[i] = camera.Direction_Fn[i]->Execute(mpFunctionContext, x0, y0);
869+
}
870+
if (cameraDirection.IsNearNull(EPSILON))
871+
return false;
872+
ray.Origin = cameraLocation;
873+
ray.Direction = cameraDirection;
874+
875+
if(useFocalBlur)
876+
JitterCameraRay(ray, x, y, ray_number);
877+
878+
InitRayContainerState(ray, true);
879+
break;
880+
849881
default:
850882
throw POV_EXCEPTION_STRING("Unknown camera type in CreateCameraRay().");
851883
}

source/core/render/tracepixel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ class TracePixel : public Trace
128128
/// whether this is just a pretrace, allowing some computations to be skipped
129129
bool pretrace;
130130

131+
/// Function execution context for user-defined camera
132+
GenericFunctionContextPtr mpFunctionContext;
133+
131134
bool CreateCameraRay(Ray& ray, DBL x, DBL y, DBL width, DBL height, size_t ray_number);
132135

133136
void InitRayContainerState(Ray& ray, bool compute = false);

source/core/scene/camera.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ void Camera::Init()
251251
Face_Distribution_Method = 0;
252252
Smooth = false;
253253
Max_Ray_Distance = 0.0;
254+
255+
for (unsigned int i = 0; i < 3; ++i)
256+
{
257+
Location_Fn[i] = NULL;
258+
Direction_Fn[i] = NULL;
259+
}
254260
}
255261

256262
/*****************************************************************************
@@ -360,6 +366,24 @@ Camera& Camera::operator=(const Camera& src)
360366
}
361367
Smooth = src.Smooth;
362368

369+
for (unsigned int i = 0; i < 3; ++i)
370+
{
371+
if (Location_Fn[i] != NULL)
372+
delete Location_Fn[i];
373+
if (src.Location_Fn[i] == NULL)
374+
Location_Fn[i] = NULL;
375+
else
376+
Location_Fn[i] = src.Location_Fn[i]->Clone();
377+
378+
if (Direction_Fn[i] != NULL)
379+
delete Direction_Fn[i];
380+
if (src.Direction_Fn[i] == NULL)
381+
Direction_Fn[i] = NULL;
382+
else
383+
Direction_Fn[i] = src.Direction_Fn[i]->Clone();
384+
385+
}
386+
363387
return *this;
364388
}
365389

@@ -368,6 +392,11 @@ Camera::Camera(const Camera& src)
368392
Tnormal = NULL;
369393
Trans = NULL;
370394
Bokeh = NULL;
395+
for (unsigned int i = 0; i < 3; ++i)
396+
{
397+
Location_Fn[i] = NULL;
398+
Direction_Fn[i] = NULL;
399+
}
371400
operator=(src);
372401
}
373402

@@ -405,6 +434,13 @@ Camera::~Camera()
405434
for (std::vector<ObjectPtr>::iterator it = Meshes.begin(); it != Meshes.end(); it++)
406435
Destroy_Object(*it);
407436
Meshes.clear();
437+
for (unsigned int i = 0; i < 3; ++i)
438+
{
439+
if (Location_Fn[i] != NULL)
440+
delete Location_Fn[i];
441+
if (Direction_Fn[i] != NULL)
442+
delete Direction_Fn[i];
443+
}
408444
}
409445

410446
}

source/core/scene/camera.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace pov
6363
#define CYL_4_CAMERA 10
6464
#define SPHERICAL_CAMERA 11
6565
#define MESH_CAMERA 12
66+
#define USER_DEFINED_CAMERA 13
6667

6768
/*****************************************************************************
6869
* Global typedefs
@@ -90,6 +91,8 @@ class Camera
9091
TNORMAL *Tnormal; // Primary ray pertubation.
9192
TRANSFORM *Trans; // Used only to record the user's input
9293
PIGMENT *Bokeh; // Pigment to use for the bokeh
94+
GenericScalarFunctionPtr Location_Fn[3]; // [USER_DEFINED_CAMERA] Set of functions defining the ray's origin for each screen position.
95+
GenericScalarFunctionPtr Direction_Fn[3]; // [USER_DEFINED_CAMERA] Set of functions defining the ray's direction for each screen position.
9396

9497
// the following declarations are used for the mesh camera
9598
unsigned int Face_Distribution_Method; // how to associate a pixel to a face within a mesh

0 commit comments

Comments
 (0)